Skip to content

Commit

Permalink
Don't supply duplicate X11 symbols inside SDL.
Browse files Browse the repository at this point in the history
Fixes static linking when something else also uses X11.
  • Loading branch information
icculus committed Oct 18, 2013
1 parent 95dc994 commit a2bd897
Show file tree
Hide file tree
Showing 15 changed files with 459 additions and 467 deletions.
26 changes: 13 additions & 13 deletions src/video/x11/SDL_x11clipboard.c
Expand Up @@ -31,7 +31,7 @@

/* If you don't support UTF-8, you might use XA_STRING here */
#ifdef X_HAVE_UTF8_STRING
#define TEXT_FORMAT XInternAtom(display, "UTF8_STRING", False)
#define TEXT_FORMAT X11_XInternAtom(display, "UTF8_STRING", False)
#else
#define TEXT_FORMAT XA_STRING
#endif
Expand All @@ -55,7 +55,7 @@ X11_SetClipboardText(_THIS, const char *text)
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
Atom format;
Window window;
Atom XA_CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0);
Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0);

/* Get the SDL window that will own the selection */
window = GetWindow(_this);
Expand All @@ -65,17 +65,17 @@ X11_SetClipboardText(_THIS, const char *text)

/* Save the selection on the root window */
format = TEXT_FORMAT;
XChangeProperty(display, DefaultRootWindow(display),
X11_XChangeProperty(display, DefaultRootWindow(display),
XA_CUT_BUFFER0, format, 8, PropModeReplace,
(const unsigned char *)text, SDL_strlen(text));

if (XA_CLIPBOARD != None &&
XGetSelectionOwner(display, XA_CLIPBOARD) != window) {
XSetSelectionOwner(display, XA_CLIPBOARD, window, CurrentTime);
X11_XGetSelectionOwner(display, XA_CLIPBOARD) != window) {
X11_XSetSelectionOwner(display, XA_CLIPBOARD, window, CurrentTime);
}

if (XGetSelectionOwner(display, XA_PRIMARY) != window) {
XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime);
if (X11_XGetSelectionOwner(display, XA_PRIMARY) != window) {
X11_XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime);
}
return 0;
}
Expand All @@ -97,7 +97,7 @@ X11_GetClipboardText(_THIS)
char *text;
Uint32 waitStart;
Uint32 waitElapsed;
Atom XA_CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0);
Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0);
if (XA_CLIPBOARD == None) {
SDL_SetError("Couldn't access X clipboard");
return SDL_strdup("");
Expand All @@ -108,15 +108,15 @@ X11_GetClipboardText(_THIS)
/* Get the window that holds the selection */
window = GetWindow(_this);
format = TEXT_FORMAT;
owner = XGetSelectionOwner(display, XA_CLIPBOARD);
owner = X11_XGetSelectionOwner(display, XA_CLIPBOARD);
if ((owner == None) || (owner == window)) {
owner = DefaultRootWindow(display);
selection = XA_CUT_BUFFER0;
} else {
/* Request that the selection owner copy the data to our window */
owner = window;
selection = XInternAtom(display, "SDL_SELECTION", False);
XConvertSelection(display, XA_CLIPBOARD, format, selection, owner,
selection = X11_XInternAtom(display, "SDL_SELECTION", False);
X11_XConvertSelection(display, XA_CLIPBOARD, format, selection, owner,
CurrentTime);

/* When using synergy on Linux and when data has been put in the clipboard
Expand All @@ -139,7 +139,7 @@ X11_GetClipboardText(_THIS)
}
}

if (XGetWindowProperty(display, owner, selection, 0, INT_MAX/4, False,
if (X11_XGetWindowProperty(display, owner, selection, 0, INT_MAX/4, False,
format, &seln_type, &seln_format, &nbytes, &overflow, &src)
== Success) {
if (seln_type == format) {
Expand All @@ -149,7 +149,7 @@ X11_GetClipboardText(_THIS)
text[nbytes] = '\0';
}
}
XFree(src);
X11_XFree(src);
}

if (!text) {
Expand Down
46 changes: 20 additions & 26 deletions src/video/x11/SDL_x11dyn.c
Expand Up @@ -103,24 +103,19 @@ X11_GetSym(const char *fnname, int *pHasModule)
return fn;
}

#endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */

/* Define all the function pointers and wrappers... */
#define SDL_X11_MODULE(modname)
#define SDL_X11_SYM(rc,fn,params,args,ret) \
typedef rc (*SDL_DYNX11FN_##fn) params; \
static SDL_DYNX11FN_##fn p##fn = NULL; \
rc fn params { ret p##fn args ; }
#define SDL_X11_SYM(rc,fn,params,args,ret) SDL_DYNX11FN_##fn X11_##fn = NULL;
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM
#endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */

/* Annoying varargs entry point... */
#ifdef X_HAVE_UTF8_STRING
typedef XIC(*SDL_DYNX11FN_XCreateIC) (XIM,...);
SDL_DYNX11FN_XCreateIC pXCreateIC = NULL;
typedef char *(*SDL_DYNX11FN_XGetICValues) (XIC, ...);
SDL_DYNX11FN_XGetICValues pXGetICValues = NULL;
SDL_DYNX11FN_XCreateIC X11_XCreateIC = NULL;
SDL_DYNX11FN_XGetICValues X11_XGetICValues = NULL;
#endif

/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
Expand All @@ -130,41 +125,38 @@ SDL_DYNX11FN_XGetICValues pXGetICValues = NULL;
#undef SDL_X11_MODULE
#undef SDL_X11_SYM


#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
static int x11_load_refcount = 0;
#endif

void
SDL_X11_UnloadSymbols(void)
{
#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
/* Don't actually unload if more than one module is using the libs... */
if (x11_load_refcount > 0) {
if (--x11_load_refcount == 0) {
int i;

/* set all the function pointers to NULL. */
#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0;
#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
#define SDL_X11_SYM(rc,fn,params,args,ret) X11_##fn = NULL;
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM

#ifdef X_HAVE_UTF8_STRING
pXCreateIC = NULL;
pXGetICValues = NULL;
X11_XCreateIC = NULL;
X11_XGetICValues = NULL;
#endif

#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
if (x11libs[i].lib != NULL) {
SDL_UnloadObject(x11libs[i].lib);
x11libs[i].lib = NULL;
}
}
#endif
}
}
#endif
}

/* returns non-zero if all needed symbols were loaded. */
Expand All @@ -173,9 +165,9 @@ SDL_X11_LoadSymbols(void)
{
int rc = 1; /* always succeed if not using Dynamic X11 stuff. */

#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
/* deal with multiple modules (dga, x11, etc) needing these symbols... */
if (x11_load_refcount++ == 0) {
#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
int i;
int *thismod = NULL;
for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
Expand All @@ -191,15 +183,15 @@ SDL_X11_LoadSymbols(void)
#undef SDL_X11_SYM

#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
#define SDL_X11_SYM(a,fn,x,y,z) p##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod);
#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod);
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM

#ifdef X_HAVE_UTF8_STRING
pXCreateIC = (SDL_DYNX11FN_XCreateIC)
X11_XCreateIC = (SDL_DYNX11FN_XCreateIC)
X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8);
pXGetICValues = (SDL_DYNX11FN_XGetICValues)
X11_XGetICValues = (SDL_DYNX11FN_XGetICValues)
X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8);
#endif

Expand All @@ -211,19 +203,21 @@ SDL_X11_LoadSymbols(void)
SDL_X11_UnloadSymbols();
rc = 0;
}
}
#else

#else /* no dynamic X11 */

#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
#define SDL_X11_SYM(a,fn,x,y,z)
#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = fn;
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM

#ifdef X_HAVE_UTF8_STRING
pXCreateIC = XCreateIC;
pXGetICValues = XGetICValues;
X11_XCreateIC = XCreateIC;
X11_XGetICValues = XGetICValues;
#endif
#endif
}

return rc;
}
Expand Down
42 changes: 20 additions & 22 deletions src/video/x11/SDL_x11dyn.h
Expand Up @@ -69,35 +69,34 @@
#include <X11/extensions/xf86vmode.h>
#endif

/*
* When using the "dynamic X11" functionality, we duplicate all the Xlib
* symbols that would be referenced by SDL inside of SDL itself.
* These duplicated symbols just serve as passthroughs to the functions
* in Xlib, that was dynamically loaded.
*
* This allows us to use Xlib as-is when linking against it directly, but
* also handles all the strange cases where there was code in the Xlib
* headers that may or may not exist or vary on a given platform.
*/
#ifdef __cplusplus
extern "C"
{
#endif

/* evil function signatures... */
typedef Bool(*SDL_X11_XESetWireToEventRetType) (Display *, XEvent *,
xEvent *);
typedef int (*SDL_X11_XSynchronizeRetType) (Display *);
typedef Status(*SDL_X11_XESetEventToWireRetType) (Display *, XEvent *,
xEvent *);

int SDL_X11_LoadSymbols(void);
void SDL_X11_UnloadSymbols(void);
typedef Bool(*SDL_X11_XESetWireToEventRetType) (Display *, XEvent *, xEvent *);
typedef int (*SDL_X11_XSynchronizeRetType) (Display *);
typedef Status(*SDL_X11_XESetEventToWireRetType) (Display *, XEvent *, xEvent *);

int SDL_X11_LoadSymbols(void);
void SDL_X11_UnloadSymbols(void);

/* Declare all the function pointers and wrappers... */
#define SDL_X11_MODULE(modname)
#define SDL_X11_SYM(rc,fn,params,args,ret) \
typedef rc (*SDL_DYNX11FN_##fn) params; \
extern SDL_DYNX11FN_##fn X11_##fn;
#include "SDL_x11sym.h"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM

/* That's really annoying...make these function pointers no matter what. */
/* Annoying varargs entry point... */
#ifdef X_HAVE_UTF8_STRING
extern XIC(*pXCreateIC) (XIM, ...);
extern char *(*pXGetICValues) (XIC, ...);
typedef XIC(*SDL_DYNX11FN_XCreateIC) (XIM,...);
typedef char *(*SDL_DYNX11FN_XGetICValues) (XIC, ...);
extern SDL_DYNX11FN_XCreateIC X11_XCreateIC;
extern SDL_DYNX11FN_XGetICValues X11_XGetICValues;
#endif

/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
Expand All @@ -107,7 +106,6 @@ extern "C"
#undef SDL_X11_MODULE
#undef SDL_X11_SYM


#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit a2bd897

Please sign in to comment.