Updated italian translation
[midnight-commander.git] / src / x11conn.c
blob8ad32816c9d3eeb6724677a2f2e8703761c250ec
1 /*
2 X11 support for the Midnight Commander.
4 Copyright (C) 2005 The Free Software Foundation
6 Written by:
7 Roland Illig <roland.illig@gmx.de>, 2005.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 !!! WARNING !!!
27 This code uses setjmp() and longjmp(). Before you modify _anything_
28 here, please read the relevant sections of the C standard.
31 #include <config.h>
33 #ifndef HAVE_TEXTMODE_X11_SUPPORT
34 typedef int dummy; /* C99 forbids empty compilation unit */
35 #else
37 #include <setjmp.h>
39 #include <X11/Xlib.h>
41 #include "../src/global.h"
43 #ifdef HAVE_GMODULE
44 # include <gmodule.h>
45 #endif
47 #include "x11conn.h"
49 /*** file scope type declarations **************************************/
51 typedef int (*mc_XErrorHandler_callback) (Display *, XErrorEvent *);
52 typedef int (*mc_XIOErrorHandler_callback) (Display *);
54 /*** file scope variables **********************************************/
56 #ifdef HAVE_GMODULE
58 static Display * (*func_XOpenDisplay) (_Xconst char *);
59 static int (*func_XCloseDisplay) (Display *);
60 static mc_XErrorHandler_callback (*func_XSetErrorHandler)
61 (mc_XErrorHandler_callback);
62 static mc_XIOErrorHandler_callback (*func_XSetIOErrorHandler)
63 (mc_XIOErrorHandler_callback);
64 static Bool (*func_XQueryPointer) (Display *, Window, Window *, Window *,
65 int *, int *, int *, int *, unsigned int *);
67 static GModule *x11_module;
69 #else
71 #define func_XOpenDisplay XOpenDisplay
72 #define func_XCloseDisplay XCloseDisplay
73 #define func_XSetErrorHandler XSetErrorHandler
74 #define func_XSetIOErrorHandler XSetIOErrorHandler
75 #define func_XQueryPointer XQueryPointer
77 #endif
79 static gboolean handlers_installed = FALSE;
81 /* This flag is set as soon as an X11 error is reported. Usually that
82 * means that the DISPLAY is not available anymore. We do not try to
83 * reconnect, as that would violate the X11 protocol. */
84 static gboolean lost_connection = FALSE;
86 static jmp_buf x11_exception; /* FIXME: get a better name */
87 static gboolean longjmp_allowed = FALSE;
89 /*** file private functions ********************************************/
91 static int x_io_error_handler (Display *dpy)
93 (void) dpy;
95 lost_connection = TRUE;
96 if (longjmp_allowed) {
97 longjmp_allowed = FALSE;
98 longjmp(x11_exception, 1);
100 return 0;
103 static int x_error_handler (Display *dpy, XErrorEvent *ee)
105 (void) ee;
106 (void) func_XCloseDisplay (dpy);
107 return x_io_error_handler (dpy);
110 static void install_error_handlers(void)
112 if (handlers_installed) return;
114 (void) func_XSetErrorHandler (x_error_handler);
115 (void) func_XSetIOErrorHandler (x_io_error_handler);
116 handlers_installed = TRUE;
119 static gboolean x11_available(void)
121 #ifdef HAVE_GMODULE
122 gchar *x11_module_fname;
124 if (lost_connection)
125 return FALSE;
127 if (x11_module != NULL)
128 return TRUE;
130 x11_module_fname = g_module_build_path (NULL, "X11");
132 if (x11_module_fname == NULL)
133 return FALSE;
135 x11_module = g_module_open (x11_module_fname, G_MODULE_BIND_LAZY);
136 g_free (x11_module_fname);
138 if (x11_module == NULL)
139 return FALSE;
141 if (!g_module_symbol (x11_module, "XOpenDisplay",
142 (void *) &func_XOpenDisplay))
143 goto cleanup;
144 if (!g_module_symbol (x11_module, "XCloseDisplay",
145 (void *) &func_XCloseDisplay))
146 goto cleanup;
147 if (!g_module_symbol (x11_module, "XQueryPointer",
148 (void *) &func_XQueryPointer))
149 goto cleanup;
150 if (!g_module_symbol (x11_module, "XSetErrorHandler",
151 (void *) &func_XSetErrorHandler))
152 goto cleanup;
153 if (!g_module_symbol (x11_module, "XSetIOErrorHandler",
154 (void *) &func_XSetIOErrorHandler))
155 goto cleanup;
157 install_error_handlers();
158 return TRUE;
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
175 /*** public functions **************************************************/
177 Display *mc_XOpenDisplay (const char *displayname)
179 Display *retval;
181 if (x11_available()) {
182 if (setjmp(x11_exception) == 0) {
183 longjmp_allowed = TRUE;
184 retval = func_XOpenDisplay (displayname);
185 longjmp_allowed = FALSE;
186 return retval;
189 return NULL;
192 int mc_XCloseDisplay (Display *display)
194 int retval;
196 if (x11_available()) {
197 if (setjmp(x11_exception) == 0) {
198 longjmp_allowed = TRUE;
199 retval = func_XCloseDisplay (display);
200 longjmp_allowed = FALSE;
201 return retval;
204 return 0;
207 Bool mc_XQueryPointer (Display *display, Window win, Window *root_return,
208 Window *child_return, int *root_x_return, int *root_y_return,
209 int *win_x_return, int *win_y_return, unsigned int *mask_return)
211 Bool retval;
213 if (x11_available()) {
214 if (setjmp(x11_exception) == 0) {
215 longjmp_allowed = TRUE;
216 retval = func_XQueryPointer (display, win, root_return,
217 child_return, root_x_return, root_y_return,
218 win_x_return, win_y_return, mask_return);
219 longjmp_allowed = FALSE;
220 return retval;
223 *root_return = None;
224 *child_return = None;
225 *root_x_return = 0;
226 *root_y_return = 0;
227 *win_x_return = 0;
228 *win_y_return = 0;
229 *mask_return = 0;
230 return False;
233 #endif /* HAVE_TEXTMODE_X11_SUPPORT */