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.
27 This code uses setjmp() and longjmp(). Before you modify _anything_
28 here, please read the relevant sections of the C standard.
33 #ifndef HAVE_TEXTMODE_X11_SUPPORT
34 typedef int dummy
; /* C99 forbids empty compilation unit */
41 #include "../src/global.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 **********************************************/
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
;
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
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
)
95 lost_connection
= TRUE
;
96 if (longjmp_allowed
) {
97 longjmp_allowed
= FALSE
;
98 longjmp(x11_exception
, 1);
103 static int x_error_handler (Display
*dpy
, XErrorEvent
*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)
122 gchar
*x11_module_fname
;
127 if (x11_module
!= NULL
)
130 x11_module_fname
= g_module_build_path (NULL
, "X11");
131 x11_module
= g_module_open (x11_module_fname
, G_MODULE_BIND_LAZY
);
132 if (x11_module
== NULL
)
133 x11_module
= g_module_open ("libX11.so.6", G_MODULE_BIND_LAZY
);
135 g_free (x11_module_fname
);
137 if (x11_module
== NULL
)
140 if (!g_module_symbol (x11_module
, "XOpenDisplay",
141 (void *) &func_XOpenDisplay
))
143 if (!g_module_symbol (x11_module
, "XCloseDisplay",
144 (void *) &func_XCloseDisplay
))
146 if (!g_module_symbol (x11_module
, "XQueryPointer",
147 (void *) &func_XQueryPointer
))
149 if (!g_module_symbol (x11_module
, "XSetErrorHandler",
150 (void *) &func_XSetErrorHandler
))
152 if (!g_module_symbol (x11_module
, "XSetIOErrorHandler",
153 (void *) &func_XSetIOErrorHandler
))
156 install_error_handlers();
160 func_XOpenDisplay
= 0;
161 func_XCloseDisplay
= 0;
162 func_XQueryPointer
= 0;
163 func_XSetErrorHandler
= 0;
164 func_XSetIOErrorHandler
= 0;
165 g_module_close (x11_module
);
169 install_error_handlers();
170 return !(lost_connection
);
174 /*** public functions **************************************************/
176 Display
*mc_XOpenDisplay (const char *displayname
)
180 if (x11_available()) {
181 if (setjmp(x11_exception
) == 0) {
182 longjmp_allowed
= TRUE
;
183 retval
= func_XOpenDisplay (displayname
);
184 longjmp_allowed
= FALSE
;
191 int mc_XCloseDisplay (Display
*display
)
195 if (x11_available()) {
196 if (setjmp(x11_exception
) == 0) {
197 longjmp_allowed
= TRUE
;
198 retval
= func_XCloseDisplay (display
);
199 longjmp_allowed
= FALSE
;
206 Bool
mc_XQueryPointer (Display
*display
, Window win
, Window
*root_return
,
207 Window
*child_return
, int *root_x_return
, int *root_y_return
,
208 int *win_x_return
, int *win_y_return
, unsigned int *mask_return
)
212 if (x11_available()) {
213 if (setjmp(x11_exception
) == 0) {
214 longjmp_allowed
= TRUE
;
215 retval
= func_XQueryPointer (display
, win
, root_return
,
216 child_return
, root_x_return
, root_y_return
,
217 win_x_return
, win_y_return
, mask_return
);
218 longjmp_allowed
= FALSE
;
223 *child_return
= None
;
232 #endif /* HAVE_TEXTMODE_X11_SUPPORT */