2 X11 support for the Midnight Commander.
4 Copyright (C) 2005, 2007 Free Software Foundation, Inc.
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 * \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.
32 #ifndef HAVE_TEXTMODE_X11_SUPPORT
33 typedef int dummy
; /* C99 forbids empty compilation unit */
42 #include "lib/global.h"
45 /*** global variables ****************************************************************************/
47 /*** file scope macro definitions ****************************************************************/
50 #define func_XOpenDisplay XOpenDisplay
51 #define func_XCloseDisplay XCloseDisplay
52 #define func_XSetErrorHandler XSetErrorHandler
53 #define func_XSetIOErrorHandler XSetIOErrorHandler
54 #define func_XQueryPointer XQueryPointer
57 /*** file scope type declarations ****************************************************************/
59 typedef int (*mc_XErrorHandler_callback
) (Display
*, XErrorEvent
*);
60 typedef int (*mc_XIOErrorHandler_callback
) (Display
*);
62 /*** file scope variables ************************************************************************/
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 static GModule
*x11_module
;
74 static gboolean handlers_installed
= FALSE
;
76 /* This flag is set as soon as an X11 error is reported. Usually that
77 * means that the DISPLAY is not available anymore. We do not try to
78 * reconnect, as that would violate the X11 protocol. */
79 static gboolean lost_connection
= FALSE
;
81 static jmp_buf x11_exception
; /* FIXME: get a better name */
82 static gboolean longjmp_allowed
= FALSE
;
84 /*** file scope functions ************************************************************************/
85 /* --------------------------------------------------------------------------------------------- */
88 x_io_error_handler (Display
* dpy
)
92 lost_connection
= TRUE
;
95 longjmp_allowed
= FALSE
;
96 longjmp (x11_exception
, 1);
101 /* --------------------------------------------------------------------------------------------- */
104 x_error_handler (Display
* dpy
, XErrorEvent
* ee
)
107 (void) func_XCloseDisplay (dpy
);
108 return x_io_error_handler (dpy
);
111 /* --------------------------------------------------------------------------------------------- */
114 install_error_handlers (void)
116 if (handlers_installed
)
119 (void) func_XSetErrorHandler (x_error_handler
);
120 (void) func_XSetIOErrorHandler (x_io_error_handler
);
121 handlers_installed
= TRUE
;
124 /* --------------------------------------------------------------------------------------------- */
130 gchar
*x11_module_fname
;
135 if (x11_module
!= NULL
)
138 x11_module_fname
= g_module_build_path (NULL
, "X11");
139 x11_module
= g_module_open (x11_module_fname
, G_MODULE_BIND_LAZY
);
140 if (x11_module
== NULL
)
141 x11_module
= g_module_open ("libX11.so.6", G_MODULE_BIND_LAZY
);
143 g_free (x11_module_fname
);
145 if (x11_module
== NULL
)
148 if (!g_module_symbol (x11_module
, "XOpenDisplay", (void *) &func_XOpenDisplay
))
150 if (!g_module_symbol (x11_module
, "XCloseDisplay", (void *) &func_XCloseDisplay
))
152 if (!g_module_symbol (x11_module
, "XQueryPointer", (void *) &func_XQueryPointer
))
154 if (!g_module_symbol (x11_module
, "XSetErrorHandler", (void *) &func_XSetErrorHandler
))
156 if (!g_module_symbol (x11_module
, "XSetIOErrorHandler", (void *) &func_XSetIOErrorHandler
))
159 install_error_handlers ();
163 func_XOpenDisplay
= 0;
164 func_XCloseDisplay
= 0;
165 func_XQueryPointer
= 0;
166 func_XSetErrorHandler
= 0;
167 func_XSetIOErrorHandler
= 0;
168 g_module_close (x11_module
);
172 install_error_handlers ();
173 return !(lost_connection
);
177 /* --------------------------------------------------------------------------------------------- */
178 /*** public functions ****************************************************************************/
179 /* --------------------------------------------------------------------------------------------- */
182 mc_XOpenDisplay (const char *displayname
)
186 if (x11_available ())
188 if (setjmp (x11_exception
) == 0)
190 longjmp_allowed
= TRUE
;
191 retval
= func_XOpenDisplay (displayname
);
192 longjmp_allowed
= FALSE
;
199 /* --------------------------------------------------------------------------------------------- */
202 mc_XCloseDisplay (Display
* display
)
206 if (x11_available ())
208 if (setjmp (x11_exception
) == 0)
210 longjmp_allowed
= TRUE
;
211 retval
= func_XCloseDisplay (display
);
212 longjmp_allowed
= FALSE
;
219 /* --------------------------------------------------------------------------------------------- */
222 mc_XQueryPointer (Display
* display
, Window win
, Window
* root_return
,
223 Window
* child_return
, int *root_x_return
, int *root_y_return
,
224 int *win_x_return
, int *win_y_return
, unsigned int *mask_return
)
228 if (x11_available ())
230 if (setjmp (x11_exception
) == 0)
232 longjmp_allowed
= TRUE
;
233 retval
= func_XQueryPointer (display
, win
, root_return
,
234 child_return
, root_x_return
, root_y_return
,
235 win_x_return
, win_y_return
, mask_return
);
236 longjmp_allowed
= FALSE
;
241 *child_return
= None
;
250 /* --------------------------------------------------------------------------------------------- */
252 #endif /* HAVE_TEXTMODE_X11_SUPPORT */