• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2012 Sam Lantinga
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14 
15     You should have received a copy of the GNU Library General Public
16     License along with this library; if not, write to the Free
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23 
24 #define DEBUG_DYNAMIC_X11 0
25 
26 #include "SDL_x11dyn.h"
27 
28 #if DEBUG_DYNAMIC_X11
29 #include <stdio.h>
30 #endif
31 
32 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
33 
34 #include "SDL_name.h"
35 #include "SDL_loadso.h"
36 
37 typedef struct
38 {
39     void *lib;
40     const char *libname;
41 } x11dynlib;
42 
43 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC
44 #define SDL_VIDEO_DRIVER_X11_DYNAMIC NULL
45 #endif
46 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
47 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL
48 #endif
49 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER
50 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER NULL
51 #endif
52 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
53 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
54 #endif
55 
56 static x11dynlib x11libs[] =
57 {
58     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC },
59     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT },
60     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER },
61     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR },
62 };
63 
X11_GetSym(const char * fnname,int * rc)64 static void *X11_GetSym(const char *fnname, int *rc)
65 {
66 	void *fn = NULL;
67 	int i;
68 	for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
69 		if (x11libs[i].lib != NULL)
70 		{
71 			fn = SDL_LoadFunction(x11libs[i].lib, fnname);
72 			if (fn != NULL)
73 				break;
74 		}
75 	}
76 
77 	#if DEBUG_DYNAMIC_X11
78 	if (fn != NULL)
79 		printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, *fn);
80 	else
81 		printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
82 	#endif
83 
84 	if (fn == NULL)
85 		*rc = 0;  /* kill this module. */
86 
87 	return fn;
88 }
89 
90 
91 /* Define all the function pointers and wrappers... */
92 #define SDL_X11_MODULE(modname)
93 #define SDL_X11_SYM(rc,fn,params,args,ret) \
94 	static rc (*p##fn) params = NULL; \
95 	rc fn params { ret p##fn args ; }
96 #include "SDL_x11sym.h"
97 #undef SDL_X11_MODULE
98 #undef SDL_X11_SYM
99 #endif  /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
100 
101 /* Annoying varargs entry point... */
102 #ifdef X_HAVE_UTF8_STRING
103 XIC (*pXCreateIC)(XIM,...) = NULL;
104 char *(*pXGetICValues)(XIC, ...) = NULL;
105 #endif
106 
107 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
108 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
109 #define SDL_X11_SYM(rc,fn,params,args,ret)
110 #include "SDL_x11sym.h"
111 #undef SDL_X11_MODULE
112 #undef SDL_X11_SYM
113 
114 
SDL_XGetRequest_workaround(Display * dpy,CARD8 type,size_t len)115 static void *SDL_XGetRequest_workaround(Display* dpy, CARD8 type, size_t len)
116 {
117 	xReq *req;
118 	WORD64ALIGN
119 	if (dpy->bufptr + len > dpy->bufmax)
120 		_XFlush(dpy);
121 	dpy->last_req = dpy->bufptr;
122 	req = (xReq*)dpy->bufptr;
123 	req->reqType = type;
124 	req->length = len / 4;
125 	dpy->bufptr += len;
126 	dpy->request++;
127 	return req;
128 }
129 
130 static int x11_load_refcount = 0;
131 
SDL_X11_UnloadSymbols(void)132 void SDL_X11_UnloadSymbols(void)
133 {
134 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
135 	/* Don't actually unload if more than one module is using the libs... */
136 	if (x11_load_refcount > 0) {
137 		if (--x11_load_refcount == 0) {
138 			int i;
139 
140 			/* set all the function pointers to NULL. */
141 			#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
142 			#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
143 			#include "SDL_x11sym.h"
144 			#undef SDL_X11_MODULE
145 			#undef SDL_X11_SYM
146 
147 			#ifdef X_HAVE_UTF8_STRING
148 			pXCreateIC = NULL;
149 			pXGetICValues = NULL;
150 			#endif
151 
152 			for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
153 				if (x11libs[i].lib != NULL) {
154 					SDL_UnloadObject(x11libs[i].lib);
155 					x11libs[i].lib = NULL;
156 				}
157 			}
158 		}
159 	}
160 	#endif
161 }
162 
163 /* returns non-zero if all needed symbols were loaded. */
SDL_X11_LoadSymbols(void)164 int SDL_X11_LoadSymbols(void)
165 {
166 	int rc = 1;  /* always succeed if not using Dynamic X11 stuff. */
167 
168 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
169 	/* deal with multiple modules (dga, x11, etc) needing these symbols... */
170 	if (x11_load_refcount++ == 0) {
171 		int i;
172 		int *thismod = NULL;
173 		for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
174 			if (x11libs[i].libname != NULL) {
175 				x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
176 			}
177 		}
178 		#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
179 		#define SDL_X11_SYM(rc,fn,params,args,ret) \
180             p##fn = (rc(*)params) X11_GetSym(#fn, thismod);
181 		#include "SDL_x11sym.h"
182 		#undef SDL_X11_MODULE
183 		#undef SDL_X11_SYM
184 
185 		#ifdef X_HAVE_UTF8_STRING
186 		pXCreateIC = (XIC(*)(XIM,...)) X11_GetSym("XCreateIC",
187 		                                          &SDL_X11_HAVE_UTF8);
188 		pXGetICValues = (char * (*)(XIC,...)) X11_GetSym("XGetICValues",
189 		                                                 &SDL_X11_HAVE_UTF8);
190 		#endif
191 
192 		/*
193 		 * In case we're built with newer Xlib headers, we need to make sure
194 		 *  that _XGetRequest() is available, even on older systems.
195 		 *  Otherwise, various Xlib macros we use will call a NULL pointer.
196 		 */
197 		if (!SDL_X11_HAVE_XGETREQUEST) {
198 			p_XGetRequest = SDL_XGetRequest_workaround;
199 		}
200 
201 		if (SDL_X11_HAVE_BASEXLIB) {  /* all required symbols loaded. */
202 			SDL_ClearError();
203 			XInitThreads();
204 		} else {
205 			SDL_X11_UnloadSymbols();  /* in case something got loaded... */
206 			rc = 0;
207 		}
208 	}
209 	#else
210 		#if DEBUG_DYNAMIC_X11
211 		printf("X11: No dynamic X11 support in this build of SDL.\n");
212 		#endif
213 		#ifdef X_HAVE_UTF8_STRING
214 		pXCreateIC = XCreateIC;
215 		pXGetICValues = XGetICValues;
216 		#endif
217 	#endif
218 
219 	return rc;
220 }
221 
222 /* end of SDL_x11dyn.c ... */
223 
224