X11 support



Hi all,

I have written a module to get the X11/GModule support out of src/key.c. Separate things---separate files.

With this module src/key.c can be simplified. I also added the framework for defining a custom error handler. This should be a good step on the way to eliminate the "openssh bug".

Roland
/* 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.
 */

#include <config.h>

#ifndef HAVE_TEXTMODE_X11_SUPPORT
typedef int dummy; /* C99 forbids empty compilation unit */
#else

#undef HAVE_GMODULE

#ifdef HAVE_GMODULE
#  include <gmodule.h>
#endif
#include <X11/Xlib.h>

#include "../src/global.h"
#include "mc-x11.h"

/*** 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 Bool (*func_XQueryPointer) (Display *, Window, Window *, Window *,
	int *, int *, int *, int *, unsigned int *);

static GModule *x11_module;
static unsigned int usage_count = 0;

#endif

/*** public functions **************************************************/

Display *mc_XOpenDisplay (const char *displayname)
{
#ifdef HAVE_GMODULE
    if (usage_count > 0) {
	return func_XOpenDisplay (displayname);
    } else {
	return NULL;
    }
#else
    return XOpenDisplay (displayname);
#endif
}

int mc_XCloseDisplay (Display *display)
{
#ifdef HAVE_GMODULE
    if (usage_count > 0) {
	return func_XCloseDisplay (display);
    } else {
	return 0;
    }
#else
    return XCloseDisplay (display);
#endif
}

mc_XErrorHandler_callback mc_XSetErrorHandler
	(mc_XErrorHandler_callback handler)
{
#ifdef HAVE_GMODULE
    if (usage_count > 0) {
	return func_XSetErrorHandler (handler);
    } else {
	return 0;
    }
#else
    return XSetErrorHandler (handler);
#endif
}

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)
{
#ifdef HAVE_GMODULE
    if (usage_count > 0) {
	return func_XQueryPointer (display, win, root_return, child_return,
		root_x_return, root_y_return, win_x_return, win_y_return,
		mask_return);
    } else {
	*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;
    }
#else
    return XQueryPointer (display, win, root_return, child_return,
	root_x_return, root_y_return, win_x_return, win_y_return,
	mask_return);
#endif
}

#ifdef HAVE_GMODULE
static gboolean gmodule_x11_init(void)
{
    gchar *x11_module_fname = g_module_build_path (NULL, "X11");

    if (!x11_module_fname)
	return FALSE;

    x11_module = g_module_open (x11_module_fname, G_MODULE_BIND_LAZY);
    g_free (x11_module_fname);

    if (!x11_module)
	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;
    return TRUE;

cleanup:
    func_XOpenDisplay = 0;
    func_XCloseDisplay = 0;
    func_XQueryPointer = 0;
    g_module_close (x11_module);
    x11_module = NULL;
    return FALSE;
}
#endif

void mc_x11_init (void)
{
#ifdef HAVE_GMODULE
    if (usage_count == 0) {
	if (gmodule_x11_init ())
	    usage_count++;
    }
#endif
}

void mc_x11_done (void)
{
#ifdef HAVE_GMODULE
    if (usage_count >= 1) {
	if (usage_count == 1)
	    g_module_close (x11_module);
	usage_count--;
    }
#endif
}

#if 1
#include <stdio.h>

int main(void)
{
	Display *dpy;
	int x, y, dummy;
	unsigned int dummymask;
	Window dummywin;
	mc_x11_init();
	dpy = mc_XOpenDisplay(NULL);
	XQueryPointer(dpy, RootWindow(dpy, DefaultScreen(dpy)), &dummywin, &dummywin, &dummy, &dummy, &x, &y, &dummymask);
	mc_XCloseDisplay(dpy);
	mc_x11_done();
	fprintf(stdout, "(%d,%d)\n", x, y);
	return 0;
}
#endif

#endif /* HAVE_TEXTMODE_X11_SUPPORT */
#ifndef MC_MC_X11_H
#define MC_MC_X11_H

/* assume HAVE_TEXTMODE_X11_SUPPORT */

#include <X11/Xlib.h>

typedef int (*mc_XErrorHandler_callback) (Display *, XErrorEvent *);

extern Display *mc_XOpenDisplay (const char *);
extern int mc_XCloseDisplay (Display *);

extern mc_XErrorHandler_callback mc_XSetErrorHandler (mc_XErrorHandler_callback);
extern Bool mc_XQueryPointer (Display *, Window, Window *, Window *, int *, int *, int *, int *, unsigned int *);

extern void mc_x11_init(void);
extern void mc_x11_done(void);

#endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]