This source file includes following definitions.
- x_io_error_handler
- x_error_handler
- install_error_handlers
- x11_available
- mc_XOpenDisplay
- mc_XCloseDisplay
- mc_XQueryPointer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include <config.h>
33
34 #include <setjmp.h>
35 #include <X11/Xlib.h>
36 #ifdef HAVE_GMODULE
37 #include <gmodule.h>
38 #endif
39
40 #include "lib/global.h"
41 #include "x11conn.h"
42
43
44
45
46
47 #ifndef HAVE_GMODULE
48 #define func_XOpenDisplay XOpenDisplay
49 #define func_XCloseDisplay XCloseDisplay
50 #define func_XSetErrorHandler XSetErrorHandler
51 #define func_XSetIOErrorHandler XSetIOErrorHandler
52 #define func_XQueryPointer XQueryPointer
53 #endif
54
55
56
57 typedef int (*mc_XErrorHandler_callback) (Display *, XErrorEvent *);
58 typedef int (*mc_XIOErrorHandler_callback) (Display *);
59
60
61
62
63
64 #ifdef HAVE_GMODULE
65 static Display *(*func_XOpenDisplay) (_Xconst char *);
66 static int (*func_XCloseDisplay) (Display *);
67 static mc_XErrorHandler_callback (*func_XSetErrorHandler) (mc_XErrorHandler_callback);
68 static mc_XIOErrorHandler_callback (*func_XSetIOErrorHandler) (mc_XIOErrorHandler_callback);
69 static Bool (*func_XQueryPointer) (Display *, Window, Window *, Window *,
70 int *, int *, int *, int *, unsigned int *);
71
72 static GModule *x11_module;
73 #endif
74
75 static gboolean handlers_installed = FALSE;
76
77
78
79
80 static gboolean lost_connection = FALSE;
81
82 static jmp_buf x11_exception;
83 static gboolean longjmp_allowed = FALSE;
84
85
86
87
88
89 static int
90 x_io_error_handler (Display *dpy)
91 {
92 (void) dpy;
93
94 lost_connection = TRUE;
95 if (longjmp_allowed)
96 {
97 longjmp_allowed = FALSE;
98 longjmp (x11_exception, 1);
99 }
100 return 0;
101 }
102
103
104
105 static int
106 x_error_handler (Display *dpy, XErrorEvent *ee)
107 {
108 (void) ee;
109 (void) func_XCloseDisplay (dpy);
110 return x_io_error_handler (dpy);
111 }
112
113
114
115 static void
116 install_error_handlers (void)
117 {
118 if (handlers_installed)
119 return;
120
121 (void) func_XSetErrorHandler (x_error_handler);
122 (void) func_XSetIOErrorHandler (x_io_error_handler);
123 handlers_installed = TRUE;
124 }
125
126
127
128 static gboolean
129 x11_available (void)
130 {
131 #ifdef HAVE_GMODULE
132 if (lost_connection)
133 return FALSE;
134
135 if (x11_module != NULL)
136 return TRUE;
137
138 x11_module = g_module_open ("X11", G_MODULE_BIND_LAZY);
139 if (x11_module == NULL)
140 x11_module = g_module_open ("libX11.so.6", G_MODULE_BIND_LAZY);
141
142 if (x11_module == NULL)
143 return FALSE;
144
145 if (!g_module_symbol (x11_module, "XOpenDisplay", (void *) &func_XOpenDisplay))
146 goto cleanup;
147 if (!g_module_symbol (x11_module, "XCloseDisplay", (void *) &func_XCloseDisplay))
148 goto cleanup;
149 if (!g_module_symbol (x11_module, "XQueryPointer", (void *) &func_XQueryPointer))
150 goto cleanup;
151 if (!g_module_symbol (x11_module, "XSetErrorHandler", (void *) &func_XSetErrorHandler))
152 goto cleanup;
153 if (!g_module_symbol (x11_module, "XSetIOErrorHandler", (void *) &func_XSetIOErrorHandler))
154 goto cleanup;
155
156 install_error_handlers ();
157 return TRUE;
158
159 cleanup:
160 func_XOpenDisplay = 0;
161 func_XCloseDisplay = 0;
162 func_XQueryPointer = 0;
163 func_XSetErrorHandler = 0;
164 func_XSetIOErrorHandler = 0;
165 g_module_close (x11_module);
166 x11_module = NULL;
167 return FALSE;
168 #else
169 install_error_handlers ();
170 return !(lost_connection);
171 #endif
172 }
173
174
175
176
177
178 Display *
179 mc_XOpenDisplay (const char *displayname)
180 {
181 if (x11_available ())
182 {
183 if (setjmp (x11_exception) == 0)
184 {
185 Display *retval;
186
187
188 longjmp_allowed = TRUE;
189
190 retval = func_XOpenDisplay (displayname);
191
192
193 longjmp_allowed = FALSE;
194 return retval;
195 }
196 }
197 return NULL;
198 }
199
200
201
202 int
203 mc_XCloseDisplay (Display *display)
204 {
205 if (x11_available ())
206 {
207 if (setjmp (x11_exception) == 0)
208 {
209 int retval;
210
211
212 longjmp_allowed = TRUE;
213
214 retval = func_XCloseDisplay (display);
215
216
217 longjmp_allowed = FALSE;
218
219 return retval;
220 }
221 }
222 return 0;
223 }
224
225
226
227 Bool
228 mc_XQueryPointer (Display *display, Window win, Window *root_return,
229 Window *child_return, int *root_x_return, int *root_y_return,
230 int *win_x_return, int *win_y_return, unsigned int *mask_return)
231 {
232 Bool retval;
233
234 if (x11_available ())
235 {
236 if (setjmp (x11_exception) == 0)
237 {
238
239 longjmp_allowed = TRUE;
240
241 retval = func_XQueryPointer (display, win, root_return,
242 child_return, root_x_return, root_y_return,
243 win_x_return, win_y_return, mask_return);
244
245
246 longjmp_allowed = FALSE;
247
248 return retval;
249 }
250 }
251 *root_return = None;
252 *child_return = None;
253 *root_x_return = 0;
254 *root_y_return = 0;
255 *win_x_return = 0;
256 *win_y_return = 0;
257 *mask_return = 0;
258 return False;
259 }
260
261