forked from AuroraMiddleware/gtk
Improve tests for X error traps, fix two bugs
* don't lose track of previous X error handler if nested traps are pushed * free any remaining traps when display is finalized Test will fail unless bug 630032 is closed so gdk_display_close() works. https://bugzilla.gnome.org/show_bug.cgi?id=630033
This commit is contained in:
parent
c7d73ee587
commit
e32ab82069
@ -1911,6 +1911,21 @@ gdk_display_x11_finalize (GObject *object)
|
||||
|
||||
XCloseDisplay (display_x11->xdisplay);
|
||||
|
||||
/* error traps */
|
||||
while (display_x11->error_traps != NULL)
|
||||
{
|
||||
GdkErrorTrap *trap = display_x11->error_traps->data;
|
||||
|
||||
display_x11->error_traps =
|
||||
g_slist_delete_link (display_x11->error_traps,
|
||||
display_x11->error_traps);
|
||||
|
||||
if (trap->end_sequence == 0)
|
||||
g_warning ("Display finalized with an unpopped error trap");
|
||||
|
||||
g_slice_free (GdkErrorTrap, trap);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (_gdk_display_x11_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,8 @@ struct _GdkPredicate
|
||||
};
|
||||
|
||||
/* non-GDK previous error handler */
|
||||
static int (*_gdk_old_error_handler) (Display *, XErrorEvent *);
|
||||
typedef int (*GdkXErrorHandler) (Display *, XErrorEvent *);
|
||||
static GdkXErrorHandler _gdk_old_error_handler;
|
||||
/* number of times we've pushed the GDK error handler */
|
||||
static int _gdk_error_handler_push_count = 0;
|
||||
|
||||
@ -386,13 +387,19 @@ gdk_x_error (Display *xdisplay,
|
||||
void
|
||||
_gdk_x11_error_handler_push (void)
|
||||
{
|
||||
_gdk_old_error_handler = XSetErrorHandler (gdk_x_error);
|
||||
GdkXErrorHandler previous;
|
||||
|
||||
previous = XSetErrorHandler (gdk_x_error);
|
||||
|
||||
if (_gdk_error_handler_push_count > 0)
|
||||
{
|
||||
if (_gdk_old_error_handler != gdk_x_error)
|
||||
if (previous != gdk_x_error)
|
||||
g_warning ("XSetErrorHandler() called with a GDK error trap pushed. Don't do that.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_old_error_handler = previous;
|
||||
}
|
||||
|
||||
_gdk_error_handler_push_count += 1;
|
||||
}
|
||||
|
@ -23,25 +23,23 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "x11/gdkx.h"
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
static void
|
||||
test_error_trapping (GdkDisplay *gdk_display)
|
||||
{
|
||||
Display *d;
|
||||
int dummy;
|
||||
int error;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
d = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
d = GDK_DISPLAY_XDISPLAY (gdk_display);
|
||||
|
||||
/* verify that we can catch errors */
|
||||
gdk_error_trap_push ();
|
||||
XListProperties (d, 0, &dummy);
|
||||
XListProperties (d, 0, &dummy); /* round trip */
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == BadWindow);
|
||||
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
XSetCloseDownMode (d, 12345); /* not a round trip */
|
||||
XSetCloseDownMode (d, DestroyAll);
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == BadValue);
|
||||
@ -58,6 +56,104 @@ main (gint argc, gchar *argv[])
|
||||
|
||||
XSync (d, TRUE);
|
||||
|
||||
/* verify that we can catch with nested traps */
|
||||
gdk_error_trap_push ();
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == BadValue);
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == BadValue);
|
||||
|
||||
/* try nested, without sync */
|
||||
gdk_error_trap_push ();
|
||||
gdk_error_trap_push ();
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
gdk_error_trap_pop_ignored ();
|
||||
gdk_error_trap_pop_ignored ();
|
||||
gdk_error_trap_pop_ignored ();
|
||||
|
||||
XSync (d, TRUE);
|
||||
|
||||
/* try nested, without sync, with interleaved calls */
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
gdk_error_trap_pop_ignored ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
gdk_error_trap_pop_ignored ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
gdk_error_trap_pop_ignored ();
|
||||
|
||||
XSync (d, TRUE);
|
||||
|
||||
/* don't want to get errors that weren't in our push range */
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
gdk_error_trap_push ();
|
||||
XSync (d, TRUE); /* not an error */
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == Success);
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == BadValue);
|
||||
|
||||
/* non-roundtrip non-error request after error request, inside trap */
|
||||
gdk_error_trap_push ();
|
||||
XSetCloseDownMode (d, 12345);
|
||||
XMapWindow (d, DefaultRootWindow (d));
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == BadValue);
|
||||
|
||||
/* a non-roundtrip non-error request before error request, inside trap */
|
||||
gdk_error_trap_push ();
|
||||
XMapWindow (d, DefaultRootWindow (d));
|
||||
XSetCloseDownMode (d, 12345);
|
||||
error = gdk_error_trap_pop ();
|
||||
g_assert (error == BadValue);
|
||||
|
||||
/* Not part of any test, just a double-check
|
||||
* that all errors have arrived
|
||||
*/
|
||||
XSync (d, TRUE);
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
{
|
||||
GdkDisplay *extra_display;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
test_error_trapping (gdk_display_get_default ());
|
||||
|
||||
extra_display = gdk_display_open (NULL);
|
||||
test_error_trapping (extra_display);
|
||||
gdk_display_close (extra_display);
|
||||
|
||||
test_error_trapping (gdk_display_get_default ());
|
||||
|
||||
/* open a display with a trap pushed and see if we
|
||||
* get confused
|
||||
*/
|
||||
gdk_error_trap_push ();
|
||||
gdk_error_trap_push ();
|
||||
|
||||
extra_display = gdk_display_open (NULL);
|
||||
test_error_trapping (extra_display);
|
||||
gdk_display_close (extra_display);
|
||||
|
||||
gdk_error_trap_pop_ignored ();
|
||||
gdk_error_trap_pop_ignored ();
|
||||
|
||||
test_error_trapping (gdk_display_get_default ());
|
||||
|
||||
/* reassure us that the tests ran. */
|
||||
g_print("All errors properly trapped.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user