From c719b4bf3d66b117003e4703eea5e15cfac8ebe5 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 27 Jun 2005 18:37:41 +0000 Subject: Avoid a segfault. (#309054) 2005-06-27 Matthias Clasen * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize): Avoid a segfault. (#309054) * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add fields for grab timestamps. * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab): Store grab timestamps when grabbing. * gdk/x11/gdkdisplay-x11.c (gdk_display_keyboard_ungrab) (gdk_display_pointer_ungrab): Don't unset the grab_window if the timestamps indicate that the ungrab will fails. --- gdk/x11/gdkdisplay-x11.c | 23 +++++++++++++++++++---- gdk/x11/gdkdisplay-x11.h | 2 ++ gdk/x11/gdkmain-x11.c | 16 ++++++++++++---- 3 files changed, 33 insertions(+), 8 deletions(-) (limited to 'gdk') diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index b73f0ea7e1..66cdc82800 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -488,6 +488,11 @@ _gdk_x11_display_is_root_window (GdkDisplay *display, return FALSE; } +#define XSERVER_TIME_IS_LATER(time1, time2) \ + ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \ + (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \ + ) + /** * gdk_display_pointer_ungrab: * @display: a #GdkDisplay. @@ -502,16 +507,21 @@ gdk_display_pointer_ungrab (GdkDisplay *display, guint32 time) { Display *xdisplay; - + GdkDisplayX11 *display_x11; + g_return_if_fail (GDK_IS_DISPLAY (display)); + display_x11 = GDK_DISPLAY_X11 (display); xdisplay = GDK_DISPLAY_XDISPLAY (display); _gdk_input_ungrab_pointer (display, time); XUngrabPointer (xdisplay, time); XFlush (xdisplay); - - GDK_DISPLAY_X11 (display)->pointer_xgrab_window = NULL; + + if (time == GDK_CURRENT_TIME || + display_x11->pointer_xgrab_time == GDK_CURRENT_TIME || + !XSERVER_TIME_IS_LATER (display_x11->pointer_xgrab_time, time)) + display_x11->pointer_xgrab_window = NULL; } /** @@ -546,15 +556,20 @@ gdk_display_keyboard_ungrab (GdkDisplay *display, guint32 time) { Display *xdisplay; + GdkDisplayX11 *display_x11; g_return_if_fail (GDK_IS_DISPLAY (display)); + display_x11 = GDK_DISPLAY_X11 (display); xdisplay = GDK_DISPLAY_XDISPLAY (display); XUngrabKeyboard (xdisplay, time); XFlush (xdisplay); - GDK_DISPLAY_X11 (display)->keyboard_xgrab_window = NULL; + if (time == GDK_CURRENT_TIME || + display_x11->keyboard_xgrab_time == GDK_CURRENT_TIME || + !XSERVER_TIME_IS_LATER (display_x11->keyboard_xgrab_time, time)) + display_x11->keyboard_xgrab_window = NULL; } /** diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 198bf6a727..3e69fa5644 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -88,10 +88,12 @@ struct _GdkDisplayX11 GdkWindowObject *pointer_xgrab_window; gulong pointer_xgrab_serial; gboolean pointer_xgrab_owner_events; + guint32 pointer_xgrab_time; GdkWindowObject *keyboard_xgrab_window; gulong keyboard_xgrab_serial; gboolean keyboard_xgrab_owner_events; + guint32 keyboard_xgrab_time; /* drag and drop information */ GdkDragContext *current_dest_drag; diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 3d60d3294a..366f709fe7 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -251,17 +251,19 @@ gdk_pointer_grab (GdkWindow * window, if (return_val == GrabSuccess) { GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); -#if 0 if (display_x11->pointer_xgrab_window != NULL) { + g_print ("overgrab pointer\n"); +#if 0 generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), FALSE); - } #endif + } display_x11->pointer_xgrab_window = (GdkWindowObject *)window; display_x11->pointer_xgrab_serial = serial; display_x11->pointer_xgrab_owner_events = owner_events; + display_x11->pointer_xgrab_time = time; } return gdk_x11_convert_grab_status (return_val); @@ -356,16 +358,18 @@ gdk_keyboard_grab (GdkWindow * window, if (return_val == GrabSuccess) { GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); -#if 0 if (display_x11->keyboard_xgrab_window != NULL) { + g_print ("overgrab keyboard\n"); +#if 0 generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), TRUE); - } #endif + } display_x11->keyboard_xgrab_window = (GdkWindowObject *)window; display_x11->keyboard_xgrab_serial = serial; display_x11->keyboard_xgrab_owner_events = owner_events; + display_x11->keyboard_xgrab_time = time; } return gdk_x11_convert_grab_status (return_val); @@ -435,6 +439,7 @@ _gdk_xgrab_check_unmap (GdkWindow *window, if (tmp) { + g_print ("pointer grab broken from check unmap\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), FALSE); display_x11->pointer_xgrab_window = NULL; @@ -453,6 +458,7 @@ _gdk_xgrab_check_unmap (GdkWindow *window, if (tmp) { + g_print ("keyboard grab broken from check unmap\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), TRUE); display_x11->keyboard_xgrab_window = NULL; @@ -474,6 +480,7 @@ _gdk_xgrab_check_destroy (GdkWindow *window) if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window) { + g_print ("pointer grab broken from check destroy\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), FALSE); display_x11->pointer_xgrab_window = NULL; @@ -481,6 +488,7 @@ _gdk_xgrab_check_destroy (GdkWindow *window) if ((GdkWindowObject *)window == display_x11->keyboard_xgrab_window) { + g_print ("keyboard grab broken from check destroy\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), TRUE); display_x11->keyboard_xgrab_window = NULL; -- cgit v1.2.1