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 #ifdef HAVE_GMODULE
63 static Display *(*func_XOpenDisplay) (_Xconst char *);
64 static int (*func_XCloseDisplay) (Display *);
65 static mc_XErrorHandler_callback (*func_XSetErrorHandler) (mc_XErrorHandler_callback);
66 static mc_XIOErrorHandler_callback (*func_XSetIOErrorHandler) (mc_XIOErrorHandler_callback);
67 static Bool (*func_XQueryPointer) (Display *, Window, Window *, Window *,
68 int *, int *, int *, int *, unsigned int *);
69 static GModule *x11_module;
70 #endif
71
72 static gboolean handlers_installed = FALSE;
73
74
75
76
77 static gboolean lost_connection = FALSE;
78
79 static jmp_buf x11_exception;
80 static gboolean longjmp_allowed = FALSE;
81
82
83
84
85 static int
86 x_io_error_handler (Display * dpy)
87 {
88 (void) dpy;
89
90 lost_connection = TRUE;
91 if (longjmp_allowed)
92 {
93 longjmp_allowed = FALSE;
94 longjmp (x11_exception, 1);
95 }
96 return 0;
97 }
98
99
100
101 static int
102 x_error_handler (Display * dpy, XErrorEvent * ee)
103 {
104 (void) ee;
105 (void) func_XCloseDisplay (dpy);
106 return x_io_error_handler (dpy);
107 }
108
109
110
111 static void
112 install_error_handlers (void)
113 {
114 if (handlers_installed)
115 return;
116
117 (void) func_XSetErrorHandler (x_error_handler);
118 (void) func_XSetIOErrorHandler (x_io_error_handler);
119 handlers_installed = TRUE;
120 }
121
122
123
124 static gboolean
125 x11_available (void)
126 {
127 #ifdef HAVE_GMODULE
128 gchar *x11_module_fname;
129
130 if (lost_connection)
131 return FALSE;
132
133 if (x11_module != NULL)
134 return TRUE;
135
136 x11_module_fname = g_module_build_path (NULL, "X11");
137 x11_module = g_module_open (x11_module_fname, G_MODULE_BIND_LAZY);
138 if (x11_module == NULL)
139 x11_module = g_module_open ("libX11.so.6", G_MODULE_BIND_LAZY);
140
141 g_free (x11_module_fname);
142
143 if (x11_module == NULL)
144 return FALSE;
145
146 if (!g_module_symbol (x11_module, "XOpenDisplay", (void *) &func_XOpenDisplay))
147 goto cleanup;
148 if (!g_module_symbol (x11_module, "XCloseDisplay", (void *) &func_XCloseDisplay))
149 goto cleanup;
150 if (!g_module_symbol (x11_module, "XQueryPointer", (void *) &func_XQueryPointer))
151 goto cleanup;
152 if (!g_module_symbol (x11_module, "XSetErrorHandler", (void *) &func_XSetErrorHandler))
153 goto cleanup;
154 if (!g_module_symbol (x11_module, "XSetIOErrorHandler", (void *) &func_XSetIOErrorHandler))
155 goto cleanup;
156
157 install_error_handlers ();
158 return TRUE;
159
160 cleanup:
161 func_XOpenDisplay = 0;
162 func_XCloseDisplay = 0;
163 func_XQueryPointer = 0;
164 func_XSetErrorHandler = 0;
165 func_XSetIOErrorHandler = 0;
166 g_module_close (x11_module);
167 x11_module = NULL;
168 return FALSE;
169 #else
170 install_error_handlers ();
171 return !(lost_connection);
172 #endif
173 }
174
175
176
177
178
179 Display *
180 mc_XOpenDisplay (const char *displayname)
181 {
182 if (x11_available ())
183 {
184 if (setjmp (x11_exception) == 0)
185 {
186 Display *retval;
187
188
189 longjmp_allowed = TRUE;
190
191 retval = func_XOpenDisplay (displayname);
192
193
194 longjmp_allowed = FALSE;
195 return retval;
196 }
197 }
198 return NULL;
199 }
200
201
202
203 int
204 mc_XCloseDisplay (Display * display)
205 {
206 if (x11_available ())
207 {
208 if (setjmp (x11_exception) == 0)
209 {
210 int retval;
211
212
213 longjmp_allowed = TRUE;
214
215 retval = func_XCloseDisplay (display);
216
217
218 longjmp_allowed = FALSE;
219
220 return retval;
221 }
222 }
223 return 0;
224 }
225
226
227
228 Bool
229 mc_XQueryPointer (Display * display, Window win, Window * root_return,
230 Window * child_return, int *root_x_return, int *root_y_return,
231 int *win_x_return, int *win_y_return, unsigned int *mask_return)
232 {
233 Bool retval;
234
235 if (x11_available ())
236 {
237 if (setjmp (x11_exception) == 0)
238 {
239
240 longjmp_allowed = TRUE;
241
242 retval = func_XQueryPointer (display, win, root_return,
243 child_return, root_x_return, root_y_return,
244 win_x_return, win_y_return, mask_return);
245
246
247 longjmp_allowed = FALSE;
248
249 return retval;
250 }
251 }
252 *root_return = None;
253 *child_return = None;
254 *root_x_return = 0;
255 *root_y_return = 0;
256 *win_x_return = 0;
257 *win_y_return = 0;
258 *mask_return = 0;
259 return False;
260 }
261
262