1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2010 Red Hat, Inc.
3  * Author: Matthias Clasen
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 #include <X11/Xlib.h>
21 #include <gtk/gtk.h>
22 #include "x11/gdkx.h"
23 
24 static void
test_error_trapping(GdkDisplay * gdk_display)25 test_error_trapping (GdkDisplay *gdk_display)
26 {
27   Display *d;
28   int dummy;
29   int error;
30 
31   d = GDK_DISPLAY_XDISPLAY (gdk_display);
32 
33   /* verify that we can catch errors */
34   gdk_x11_display_error_trap_push (gdk_display);
35   XListProperties (d, 0, &dummy); /* round trip */
36   error = gdk_x11_display_error_trap_pop (gdk_display);
37   g_assert_true (error == BadWindow);
38 
39   gdk_x11_display_error_trap_push (gdk_display);
40   XSetCloseDownMode (d, 12345); /* not a round trip */
41   XSetCloseDownMode (d, DestroyAll);
42   error = gdk_x11_display_error_trap_pop (gdk_display);
43   g_assert_true (error == BadValue);
44 
45   /* try the same without sync */
46   gdk_x11_display_error_trap_push (gdk_display);
47   XListProperties (d, 0, &dummy);
48   gdk_x11_display_error_trap_pop_ignored (gdk_display);
49 
50   gdk_x11_display_error_trap_push (gdk_display);
51   XSetCloseDownMode (d, 12345);
52   XSetCloseDownMode (d, DestroyAll);
53   gdk_x11_display_error_trap_pop_ignored (gdk_display);
54 
55   XSync (d, TRUE);
56 
57   /* verify that we can catch with nested traps; inner-most
58    * active trap gets the error */
59   gdk_x11_display_error_trap_push (gdk_display);
60   gdk_x11_display_error_trap_push (gdk_display);
61   XSetCloseDownMode (d, 12345);
62   error = gdk_x11_display_error_trap_pop (gdk_display);
63   g_assert_true (error == BadValue);
64   error = gdk_x11_display_error_trap_pop (gdk_display);
65   g_assert_true (error == Success);
66 
67   gdk_x11_display_error_trap_push (gdk_display);
68   XSetCloseDownMode (d, 12345);
69   gdk_x11_display_error_trap_push (gdk_display);
70   error = gdk_x11_display_error_trap_pop (gdk_display);
71   g_assert_true (error == Success);
72   error = gdk_x11_display_error_trap_pop (gdk_display);
73   g_assert_true (error == BadValue);
74 
75   /* try nested, without sync */
76   gdk_x11_display_error_trap_push (gdk_display);
77   gdk_x11_display_error_trap_push (gdk_display);
78   gdk_x11_display_error_trap_push (gdk_display);
79   XSetCloseDownMode (d, 12345);
80   gdk_x11_display_error_trap_pop_ignored (gdk_display);
81   gdk_x11_display_error_trap_pop_ignored (gdk_display);
82   gdk_x11_display_error_trap_pop_ignored (gdk_display);
83 
84   XSync (d, TRUE);
85 
86   /* try nested, without sync, with interleaved calls */
87   gdk_x11_display_error_trap_push (gdk_display);
88   XSetCloseDownMode (d, 12345);
89   gdk_x11_display_error_trap_push (gdk_display);
90   XSetCloseDownMode (d, 12345);
91   gdk_x11_display_error_trap_push (gdk_display);
92   XSetCloseDownMode (d, 12345);
93   gdk_x11_display_error_trap_pop_ignored (gdk_display);
94   XSetCloseDownMode (d, 12345);
95   gdk_x11_display_error_trap_pop_ignored (gdk_display);
96   XSetCloseDownMode (d, 12345);
97   gdk_x11_display_error_trap_pop_ignored (gdk_display);
98 
99   XSync (d, TRUE);
100 
101   /* don't want to get errors that weren't in our push range */
102   gdk_x11_display_error_trap_push (gdk_display);
103   XSetCloseDownMode (d, 12345);
104   gdk_x11_display_error_trap_push (gdk_display);
105   XSync (d, TRUE); /* not an error */
106   error = gdk_x11_display_error_trap_pop (gdk_display);
107   g_assert_true (error == Success);
108   error = gdk_x11_display_error_trap_pop (gdk_display);
109   g_assert_true (error == BadValue);
110 
111   /* non-roundtrip non-error request after error request, inside trap */
112   gdk_x11_display_error_trap_push (gdk_display);
113   XSetCloseDownMode (d, 12345);
114   XMapWindow (d, DefaultRootWindow (d));
115   error = gdk_x11_display_error_trap_pop (gdk_display);
116   g_assert_true (error == BadValue);
117 
118   /* a non-roundtrip non-error request before error request, inside trap */
119   gdk_x11_display_error_trap_push (gdk_display);
120   XMapWindow (d, DefaultRootWindow (d));
121   XSetCloseDownMode (d, 12345);
122   error = gdk_x11_display_error_trap_pop (gdk_display);
123   g_assert_true (error == BadValue);
124 
125   /* Not part of any test, just a double-check
126    * that all errors have arrived
127    */
128   XSync (d, TRUE);
129 }
130 
131 int
main(int argc,char * argv[])132 main (int argc, char *argv[])
133 {
134   GdkDisplay *gdk_display;
135   GdkDisplay *extra_display;
136 
137   gtk_init ();
138 
139   gdk_display = gdk_display_get_default ();
140   test_error_trapping (gdk_display);
141 
142   extra_display = gdk_display_open (NULL);
143   test_error_trapping (extra_display);
144   gdk_display_close (extra_display);
145 
146   test_error_trapping (gdk_display_get_default ());
147 
148   /* open a display with a trap pushed and see if we
149    * get confused
150    */
151   gdk_x11_display_error_trap_push (gdk_display);
152   gdk_x11_display_error_trap_push (gdk_display);
153 
154   extra_display = gdk_display_open (NULL);
155   test_error_trapping (extra_display);
156   gdk_display_close (extra_display);
157 
158   gdk_x11_display_error_trap_pop_ignored (gdk_display);
159   gdk_x11_display_error_trap_pop_ignored (gdk_display);
160 
161   test_error_trapping (gdk_display_get_default ());
162 
163   /* reassure us that the tests ran. */
164   g_print("All errors properly trapped.\n");
165 
166   return 0;
167 }
168 
169