loadable xcursor problem with static linking

Steven Doerfler sgd-xorglist at lugaru.com
Wed Apr 18 13:06:50 PDT 2007


I'm finding that statically linked X11 programs get a runtime error due to
a dynamic cursor feature if they call certain cursor-related functions like
XCreateBitmapFromData().

I found this when updating my Debian system to 4.0, which updated the
libx11 code, introducing this problem.  Test program is below.  It runs
fine if you remove the #if 1 block, but gets an error

XIO:  fatal IO error 0 (Success) on X server "127.0.0.1:11.0"
      after 11 requests (6 known processed) with 0 events remaining.

if you don't.  Compile with 

cc -static -o hello -Wall -I/usr/X11R6/include hello.c -L/usr/X11R6/lib 
   -lX11 -lXau -lXdmcp -ldl -lpthread

The linker warns, for certain functions (a helper function of
XCreateGlyphCursor, and functions related to opening the display), that
using them in "statically linked applications requires at runtime the
shared libraries from the glibc version used for linking".  I don't think
that's the real issue here, since this is occurring on the same system
where I'm compiling.  In my actual program, I ensure that opening the
display never needs to load any shared library, leaving only the
XCreateGlyphCursor issue.

The underlying cause is that the function XCreateGlyphCursor has a
compile-time option USE_DYNAMIC_XCURSOR that makes it use dlopen() to load
a shared library.  This fails.

I think this compile-time option should default to off when building a
static version of the libx11 library.

If this should be on a different list, I'd appreciate a pointer.  Thanks.

Steven Doerfler
Lugaru Software, Ltd.
http://www.lugaru.com

********** Test case hello.c follows **********

#include<X11/Xlib.h>

#include<stdio.h>
#include<stdlib.h>

#define icon_width 32
#define icon_height 32
static unsigned char icon_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

int main()
{
	Display *dpy;
	Window rootwin;
	Window win;
	Colormap cmap;
	XEvent e;
	int scr;
	GC gc;
	if(!(dpy=XOpenDisplay(NULL))) {
		fprintf(stderr, "ERROR: could not open display\n");
		exit(1);
	}
	scr=DefaultScreen(dpy);
	rootwin=RootWindow(dpy, scr);
	cmap=DefaultColormap(dpy, scr);
	win=XCreateSimpleWindow(dpy, rootwin, 1, 1, 100, 50, 0, 
				BlackPixel(dpy, scr), BlackPixel(dpy, scr));
	XStoreName(dpy, win, "hello");
	gc=XCreateGC(dpy, win, 0, NULL);
	XSetForeground(dpy, gc, WhitePixel(dpy, scr));
#if 1
	XCreateBitmapFromData(dpy, win, (const char *) icon_bits,
		icon_width, icon_height);
#endif
	XSelectInput(dpy, win, ExposureMask|ButtonPressMask);
	XMapWindow(dpy, win);
	while(1) {
		XNextEvent(dpy, &e);
		if(e.type==Expose && e.xexpose.count<1)
			XDrawString(dpy, win, gc, 10, 10, "Hello World!", 12);
		else if(e.type==ButtonPress) break;
	}
	XCloseDisplay(dpy);
	return 0;
}




More information about the xorg mailing list