Moved dir $(srcdir)/syntax into $(srcdir)/misc/syntax
[midnight-commander.git] / src / tty / x11conn.c
blob3773a88cc69a34579e2fd949580d1af85646a320
1 /*
2 X11 support for the Midnight Commander.
4 Copyright (C) 2005, 2007 Free Software Foundation, Inc.
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.
24 /** \file x11conn.c
25 * \brief Source: X11 support
26 * \warning This code uses setjmp() and longjmp(). Before you modify _anything_ here,
27 * please read the relevant sections of the C standard.
30 #include <config.h>
32 #ifndef HAVE_TEXTMODE_X11_SUPPORT
33 typedef int dummy; /* C99 forbids empty compilation unit */
34 #else
36 #include <setjmp.h>
37 #include <X11/Xlib.h>
38 #ifdef HAVE_GMODULE
39 # include <gmodule.h>
40 #endif
42 #include "../../src/global.h"
43 #include "../../src/tty/x11conn.h"
45 /*** file scope type declarations **************************************/
47 typedef int (*mc_XErrorHandler_callback) (Display *, XErrorEvent *);
48 typedef int (*mc_XIOErrorHandler_callback) (Display *);
50 /*** file scope variables **********************************************/
52 #ifdef HAVE_GMODULE
54 static Display *(*func_XOpenDisplay) (_Xconst char *);
55 static int (*func_XCloseDisplay) (Display *);
56 static mc_XErrorHandler_callback (*func_XSetErrorHandler)
57 (mc_XErrorHandler_callback);
58 static mc_XIOErrorHandler_callback (*func_XSetIOErrorHandler)
59 (mc_XIOErrorHandler_callback);
60 static Bool (*func_XQueryPointer) (Display *, Window, Window *, Window *,
61 int *, int *, int *, int *, unsigned int *);
63 static GModule *x11_module;
65 #else
67 #define func_XOpenDisplay XOpenDisplay
68 #define func_XCloseDisplay XCloseDisplay
69 #define func_XSetErrorHandler XSetErrorHandler
70 #define func_XSetIOErrorHandler XSetIOErrorHandler
71 #define func_XQueryPointer XQueryPointer
73 #endif
75 static gboolean handlers_installed = FALSE;
77 /* This flag is set as soon as an X11 error is reported. Usually that
78 * means that the DISPLAY is not available anymore. We do not try to
79 * reconnect, as that would violate the X11 protocol. */
80 static gboolean lost_connection = FALSE;
82 static jmp_buf x11_exception; /* FIXME: get a better name */
83 static gboolean longjmp_allowed = FALSE;
85 /*** file private functions ********************************************/
87 static int
88 x_io_error_handler (Display * dpy)
90 (void) dpy;
92 lost_connection = TRUE;
93 if (longjmp_allowed) {
94 longjmp_allowed = FALSE;
95 longjmp (x11_exception, 1);
97 return 0;
100 static int
101 x_error_handler (Display * dpy, XErrorEvent * ee)
103 (void) ee;
104 (void) func_XCloseDisplay (dpy);
105 return x_io_error_handler (dpy);
108 static void
109 install_error_handlers (void)
111 if (handlers_installed)
112 return;
114 (void) func_XSetErrorHandler (x_error_handler);
115 (void) func_XSetIOErrorHandler (x_io_error_handler);
116 handlers_installed = TRUE;
119 static gboolean
120 x11_available (void)
122 #ifdef HAVE_GMODULE
123 gchar *x11_module_fname;
125 if (lost_connection)
126 return FALSE;
128 if (x11_module != NULL)
129 return TRUE;
131 x11_module_fname = g_module_build_path (NULL, "X11");
132 x11_module = g_module_open (x11_module_fname, G_MODULE_BIND_LAZY);
133 if (x11_module == NULL)
134 x11_module = g_module_open ("libX11.so.6", 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", (void *) &func_XOpenDisplay))
142 goto cleanup;
143 if (!g_module_symbol (x11_module, "XCloseDisplay", (void *) &func_XCloseDisplay))
144 goto cleanup;
145 if (!g_module_symbol (x11_module, "XQueryPointer", (void *) &func_XQueryPointer))
146 goto cleanup;
147 if (!g_module_symbol (x11_module, "XSetErrorHandler", (void *) &func_XSetErrorHandler))
148 goto cleanup;
149 if (!g_module_symbol (x11_module, "XSetIOErrorHandler", (void *) &func_XSetIOErrorHandler))
150 goto cleanup;
152 install_error_handlers ();
153 return TRUE;
155 cleanup:
156 func_XOpenDisplay = 0;
157 func_XCloseDisplay = 0;
158 func_XQueryPointer = 0;
159 func_XSetErrorHandler = 0;
160 func_XSetIOErrorHandler = 0;
161 g_module_close (x11_module);
162 x11_module = NULL;
163 return FALSE;
164 #else
165 install_error_handlers ();
166 return !(lost_connection);
167 #endif
170 /*** public functions **************************************************/
172 Display *
173 mc_XOpenDisplay (const char *displayname)
175 Display *retval;
177 if (x11_available ()) {
178 if (setjmp (x11_exception) == 0) {
179 longjmp_allowed = TRUE;
180 retval = func_XOpenDisplay (displayname);
181 longjmp_allowed = FALSE;
182 return retval;
185 return NULL;
189 mc_XCloseDisplay (Display * display)
191 int retval;
193 if (x11_available ()) {
194 if (setjmp (x11_exception) == 0) {
195 longjmp_allowed = TRUE;
196 retval = func_XCloseDisplay (display);
197 longjmp_allowed = FALSE;
198 return retval;
201 return 0;
204 Bool
205 mc_XQueryPointer (Display * display, Window win, Window * root_return,
206 Window * child_return, int *root_x_return, int *root_y_return,
207 int *win_x_return, int *win_y_return, unsigned int *mask_return)
209 Bool retval;
211 if (x11_available ()) {
212 if (setjmp (x11_exception) == 0) {
213 longjmp_allowed = TRUE;
214 retval = func_XQueryPointer (display, win, root_return,
215 child_return, root_x_return, root_y_return,
216 win_x_return, win_y_return, mask_return);
217 longjmp_allowed = FALSE;
218 return retval;
221 *root_return = None;
222 *child_return = None;
223 *root_x_return = 0;
224 *root_y_return = 0;
225 *win_x_return = 0;
226 *win_y_return = 0;
227 *mask_return = 0;
228 return False;
231 #endif /* HAVE_TEXTMODE_X11_SUPPORT */