* x11conn.c: Separated X11 connection handling from key.c. Added

error handling for X11 errors and connection errors.
	* x11conn.h: The interface for x11conn.h.
	* key.c: Now using the x11conn code.
	* Makefile.am: Added x11conn.{h,c}.
This commit is contained in:
Roland Illig 2005-03-10 09:44:36 +00:00
parent 8a4f10f52f
commit 13a63f21c9
5 changed files with 268 additions and 57 deletions

View File

@ -1,3 +1,11 @@
2005-03-10 Roland Illig <roland.illig@gmx.de>
* x11conn.c: Separated X11 connection handling from key.c. Added
error handling for X11 errors and connection errors.
* x11conn.h: The interface for x11conn.h.
* key.c: Now using the x11conn code.
* Makefile.am: Added x11conn.{h,c}.
2005-02-26 Miguel de Icaza <miguel@novell.com>
* screen.c (chdir_other_panel): Restored original functionality.

View File

@ -59,7 +59,8 @@ SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \
slint.c subshell.c subshell.h textconf.c textconf.h \
tree.c tree.h treestore.c treestore.h tty.h user.c user.h \
util.c util.h utilunix.c view.c view.h vfsdummy.h widget.c \
widget.h win.c win.h wtools.c wtools.h unixcompat.h
widget.h win.c win.h wtools.c wtools.h unixcompat.h \
x11conn.h x11conn.c
if CHARSET
mc_SOURCES = $(SRCS) $(CHARSET_SRC)

View File

@ -45,10 +45,7 @@
#endif
#ifdef HAVE_TEXTMODE_X11_SUPPORT
#ifdef HAVE_GMODULE
#include <gmodule.h>
#endif /* HAVE_GMODULE */
#include <X11/Xlib.h>
# include "x11conn.h"
#endif
#ifdef __linux__
@ -406,52 +403,16 @@ define_sequences (key_define_t *kd)
#ifdef HAVE_TEXTMODE_X11_SUPPORT
#ifdef HAVE_GMODULE
static int (*func_XCloseDisplay) (Display *);
static Bool (*func_XQueryPointer) (Display *, Window, Window *, Window *,
int *, int *, int *, int *,
unsigned int *);
static GModule *x11_module;
#endif /* HAVE_GMODULE */
static Display *x11_display;
static Window x11_window;
static void
init_key_x11 (void)
{
#ifdef HAVE_GMODULE
static Display *(*func_XOpenDisplay) (_Xconst char *);
gchar *x11_module_fname;
#endif /* HAVE_GMODULE */
if (!getenv ("DISPLAY"))
return;
#ifdef HAVE_GMODULE
x11_module_fname = g_module_build_path (NULL, "X11");
if (!x11_module_fname)
return;
x11_module = g_module_open (x11_module_fname, G_MODULE_BIND_LAZY);
g_free (x11_module_fname);
if (!x11_module)
return;
if (g_module_symbol
(x11_module, "XOpenDisplay", (void *) &func_XOpenDisplay)
&& g_module_symbol (x11_module, "XCloseDisplay",
(void *) &func_XCloseDisplay)
&& g_module_symbol (x11_module, "XQueryPointer",
(void *) &func_XQueryPointer)) {
x11_display = (*func_XOpenDisplay) (0);
}
#else
x11_display = XOpenDisplay (0);
#endif /* HAVE_GMODULE */
x11_display = mc_XOpenDisplay (0);
if (x11_display)
x11_window = DefaultRootWindow (x11_display);
@ -1324,13 +1285,8 @@ get_modifier (void)
int win_x, win_y;
unsigned int mask;
#ifdef HAVE_GMODULE
(*func_XQueryPointer) (x11_display, x11_window, &root, &child,
&root_x, &root_y, &win_x, &win_y, &mask);
#else
XQueryPointer (x11_display, x11_window, &root, &child, &root_x,
mc_XQueryPointer (x11_display, x11_window, &root, &child, &root_x,
&root_y, &win_x, &win_y, &mask);
#endif /* HAVE_GMODULE */
if (mask & ShiftMask)
result |= KEY_M_SHIFT;
@ -1440,14 +1396,7 @@ void done_key ()
s_dispose (select_list);
#ifdef HAVE_TEXTMODE_X11_SUPPORT
#ifdef HAVE_GMODULE
if (x11_display)
(*func_XCloseDisplay) (x11_display);
if (x11_module)
g_module_close (x11_module);
#else
if (x11_display)
XCloseDisplay (x11_display);
#endif /* HAVE_GMODULE */
#endif /* HAVE_TEXTMODE_X11_SUPPORT */
mc_XCloseDisplay (x11_display);
#endif
}

232
src/x11conn.c Normal file
View File

@ -0,0 +1,232 @@
/*
X11 support for the Midnight Commander.
Copyright (C) 2005 The Free Software Foundation
Written by:
Roland Illig <roland.illig@gmx.de>, 2005.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
!!! WARNING !!!
This code uses setjmp() and longjmp(). Before you modify _anything_
here, please read the relevant sections of the C standard.
*/
#include <config.h>
#ifndef HAVE_TEXTMODE_X11_SUPPORT
typedef int dummy; /* C99 forbids empty compilation unit */
#else
#include <setjmp.h>
#include <X11/Xlib.h>
#include "../src/global.h"
#ifdef HAVE_GMODULE
# include <gmodule.h>
#endif
#include "x11conn.h"
/*** file scope type declarations **************************************/
typedef int (*mc_XErrorHandler_callback) (Display *, XErrorEvent *);
typedef int (*mc_XIOErrorHandler_callback) (Display *);
/*** file scope variables **********************************************/
#ifdef HAVE_GMODULE
static Display * (*func_XOpenDisplay) (_Xconst char *);
static int (*func_XCloseDisplay) (Display *);
static mc_XErrorHandler_callback (*func_XSetErrorHandler)
(mc_XErrorHandler_callback);
static mc_XIOErrorHandler_callback (*func_XSetIOErrorHandler)
(mc_XIOErrorHandler_callback);
static Bool (*func_XQueryPointer) (Display *, Window, Window *, Window *,
int *, int *, int *, int *, unsigned int *);
static GModule *x11_module;
#else
#define func_XOpenDisplay XOpenDisplay
#define func_XCloseDisplay XCloseDisplay
#define func_XSetErrorHandler XSetErrorHandler
#define func_XSetIOErrorHandler XSetIOErrorHandler
#define func_XQueryPointer XQueryPointer
#endif
static gboolean handlers_installed = FALSE;
/* This flag is set as soon as an X11 error is reported. Usually that
* means that the DISPLAY is not available anymore. We do not try to
* reconnect, as that would violate the X11 protocol. */
static gboolean lost_connection = FALSE;
static jmp_buf x11_exception; /* FIXME: get a better name */
static gboolean longjmp_allowed = FALSE;
/*** file private functions ********************************************/
static int x_io_error_handler (Display *dpy)
{
(void) dpy;
lost_connection = TRUE;
if (longjmp_allowed) {
longjmp_allowed = FALSE;
longjmp(x11_exception, 1);
}
return 0;
}
static int x_error_handler (Display *dpy, XErrorEvent *ee)
{
(void) ee;
return x_io_error_handler (dpy);
}
static void install_error_handlers(void)
{
if (handlers_installed) return;
(void) func_XSetErrorHandler (x_error_handler);
(void) func_XSetIOErrorHandler (x_io_error_handler);
handlers_installed = TRUE;
}
static gboolean x11_available(void)
{
#ifdef HAVE_GMODULE
gchar *x11_module_fname;
if (lost_connection)
return FALSE;
if (x11_module != NULL)
return TRUE;
x11_module_fname = g_module_build_path (NULL, "X11");
if (x11_module_fname == NULL)
return FALSE;
x11_module = g_module_open (x11_module_fname, G_MODULE_BIND_LAZY);
g_free (x11_module_fname);
if (x11_module == NULL)
return FALSE;
if (!g_module_symbol (x11_module, "XOpenDisplay",
(void *) &func_XOpenDisplay))
goto cleanup;
if (!g_module_symbol (x11_module, "XCloseDisplay",
(void *) &func_XCloseDisplay))
goto cleanup;
if (!g_module_symbol (x11_module, "XQueryPointer",
(void *) &func_XQueryPointer))
goto cleanup;
if (!g_module_symbol (x11_module, "XSetErrorHandler",
(void *) &func_XSetErrorHandler))
goto cleanup;
if (!g_module_symbol (x11_module, "XSetIOErrorHandler",
(void *) &func_XSetIOErrorHandler))
goto cleanup;
install_error_handlers();
return TRUE;
cleanup:
func_XOpenDisplay = 0;
func_XCloseDisplay = 0;
func_XQueryPointer = 0;
func_XSetErrorHandler = 0;
func_XSetIOErrorHandler = 0;
g_module_close (x11_module);
x11_module = NULL;
return FALSE;
#else
install_error_handlers();
return !(lost_connection);
#endif
}
/*** public functions **************************************************/
Display *mc_XOpenDisplay (const char *displayname)
{
Display *retval;
if (x11_available()) {
if (setjmp(x11_exception) == 0) {
longjmp_allowed = TRUE;
retval = func_XOpenDisplay (displayname);
longjmp_allowed = FALSE;
return retval;
}
}
return NULL;
}
int mc_XCloseDisplay (Display *display)
{
int retval;
if (x11_available()) {
if (setjmp(x11_exception) == 0) {
longjmp_allowed = TRUE;
retval = func_XCloseDisplay (display);
longjmp_allowed = FALSE;
return retval;
}
}
return 0;
}
Bool mc_XQueryPointer (Display *display, Window win, Window *root_return,
Window *child_return, int *root_x_return, int *root_y_return,
int *win_x_return, int *win_y_return, unsigned int *mask_return)
{
Bool retval;
if (x11_available()) {
if (setjmp(x11_exception) == 0) {
longjmp_allowed = TRUE;
retval = func_XQueryPointer (display, win, root_return,
child_return, root_x_return, root_y_return,
win_x_return, win_y_return, mask_return);
longjmp_allowed = FALSE;
return retval;
}
}
*root_return = None;
*child_return = None;
*root_x_return = 0;
*root_y_return = 0;
*win_x_return = 0;
*win_y_return = 0;
*mask_return = 0;
return False;
}
#endif /* HAVE_TEXTMODE_X11_SUPPORT */

21
src/x11conn.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef MC_X11CONN_H
#define MC_X11CONN_H
/*
This module provides support for some X11 functions. The functions
are loaded dynamically if GModule is available, and statically if
not. X11 session handling is somewhat robust. If there is an X11
error or a connection error, all further traffic to the X server
will be suppressed, and the functions will return reasonable default
values.
*/
#include <X11/Xlib.h>
extern Display *mc_XOpenDisplay (const char *);
extern int mc_XCloseDisplay (Display *);
extern Bool mc_XQueryPointer (Display *, Window, Window *, Window *,
int *, int *, int *, int *, unsigned int *);
#endif