2 X11 support for the Midnight Commander.
4 Copyright (C) 2005-2019
5 Free Software Foundation, Inc.
8 Roland Illig <roland.illig@gmx.de>, 2005.
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software: you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation, either version 3 of the License,
15 or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 * \brief Source: X11 support
28 * \warning This code uses setjmp() and longjmp(). Before you modify _anything_ here,
29 * please read the relevant sections of the C standard.
40 #include "lib/global.h"
43 /*** global variables ****************************************************************************/
45 /*** file scope macro definitions ****************************************************************/
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
55 /*** file scope type declarations ****************************************************************/
57 typedef int (*mc_XErrorHandler_callback
) (Display
*, XErrorEvent
*);
58 typedef int (*mc_XIOErrorHandler_callback
) (Display
*);
60 /*** file scope variables ************************************************************************/
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
;
72 static gboolean handlers_installed
= FALSE
;
74 /* This flag is set as soon as an X11 error is reported. Usually that
75 * means that the DISPLAY is not available anymore. We do not try to
76 * reconnect, as that would violate the X11 protocol. */
77 static gboolean lost_connection
= FALSE
;
79 static jmp_buf x11_exception
; /* FIXME: get a better name */
80 static gboolean longjmp_allowed
= FALSE
;
82 /*** file scope functions ************************************************************************/
83 /* --------------------------------------------------------------------------------------------- */
86 x_io_error_handler (Display
* dpy
)
90 lost_connection
= TRUE
;
93 longjmp_allowed
= FALSE
;
94 longjmp (x11_exception
, 1);
99 /* --------------------------------------------------------------------------------------------- */
102 x_error_handler (Display
* dpy
, XErrorEvent
* ee
)
105 (void) func_XCloseDisplay (dpy
);
106 return x_io_error_handler (dpy
);
109 /* --------------------------------------------------------------------------------------------- */
112 install_error_handlers (void)
114 if (handlers_installed
)
117 (void) func_XSetErrorHandler (x_error_handler
);
118 (void) func_XSetIOErrorHandler (x_io_error_handler
);
119 handlers_installed
= TRUE
;
122 /* --------------------------------------------------------------------------------------------- */
128 gchar
*x11_module_fname
;
133 if (x11_module
!= NULL
)
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
);
141 g_free (x11_module_fname
);
143 if (x11_module
== NULL
)
146 if (!g_module_symbol (x11_module
, "XOpenDisplay", (void *) &func_XOpenDisplay
))
148 if (!g_module_symbol (x11_module
, "XCloseDisplay", (void *) &func_XCloseDisplay
))
150 if (!g_module_symbol (x11_module
, "XQueryPointer", (void *) &func_XQueryPointer
))
152 if (!g_module_symbol (x11_module
, "XSetErrorHandler", (void *) &func_XSetErrorHandler
))
154 if (!g_module_symbol (x11_module
, "XSetIOErrorHandler", (void *) &func_XSetIOErrorHandler
))
157 install_error_handlers ();
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
);
170 install_error_handlers ();
171 return !(lost_connection
);
175 /* --------------------------------------------------------------------------------------------- */
176 /*** public functions ****************************************************************************/
177 /* --------------------------------------------------------------------------------------------- */
180 mc_XOpenDisplay (const char *displayname
)
182 if (x11_available ())
184 if (setjmp (x11_exception
) == 0)
188 /* cppcheck-suppress redundantAssignment */
189 longjmp_allowed
= TRUE
;
191 retval
= func_XOpenDisplay (displayname
);
193 /* cppcheck-suppress redundantAssignment */
194 longjmp_allowed
= FALSE
;
201 /* --------------------------------------------------------------------------------------------- */
204 mc_XCloseDisplay (Display
* display
)
206 if (x11_available ())
208 if (setjmp (x11_exception
) == 0)
212 /* cppcheck-suppress redundantAssignment */
213 longjmp_allowed
= TRUE
;
215 retval
= func_XCloseDisplay (display
);
217 /* cppcheck-suppress redundantAssignment */
218 longjmp_allowed
= FALSE
;
226 /* --------------------------------------------------------------------------------------------- */
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
)
235 if (x11_available ())
237 if (setjmp (x11_exception
) == 0)
239 /* cppcheck-suppress redundantAssignment */
240 longjmp_allowed
= TRUE
;
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
);
246 /* cppcheck-suppress redundantAssignment */
247 longjmp_allowed
= FALSE
;
253 *child_return
= None
;
262 /* --------------------------------------------------------------------------------------------- */