diff options
author | Franklin Wei <git@fwei.tk> | 2018-02-07 20:04:46 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2018-03-12 20:52:01 -0400 |
commit | 6039eb05ba6d82ef56f2868c96654c552d117bf9 (patch) | |
tree | 9db7016bcbf66cfdf7b9bc998d84c6eaff9c8378 /apps/plugins/sdl/src/video/x11 | |
parent | ef373c03b96b0be08babca581d9f10bccfd4931f (diff) | |
download | rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.tar.gz rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.zip |
sdl: remove non-rockbox drivers
We never use any of these other drivers, so having them around just takes
up space.
Change-Id: Iced812162df1fef3fd55522b7e700acb6c3bcd41
Diffstat (limited to 'apps/plugins/sdl/src/video/x11')
23 files changed, 0 insertions, 7630 deletions
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11dga.c b/apps/plugins/sdl/src/video/x11/SDL_x11dga.c deleted file mode 100644 index e1c0c2e8cd..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11dga.c +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* This is currently only used to enable DGA mouse. | ||
25 | There is a completely separate DGA driver that is fullscreen-only. | ||
26 | */ | ||
27 | |||
28 | #include "SDL_video.h" | ||
29 | #include "../SDL_cursor_c.h" | ||
30 | #include "SDL_x11dga_c.h" | ||
31 | |||
32 | /* Global for the error handler */ | ||
33 | int dga_event, dga_error = -1; | ||
34 | |||
35 | void X11_EnableDGAMouse(_THIS) | ||
36 | { | ||
37 | #if SDL_VIDEO_DRIVER_X11_DGAMOUSE | ||
38 | static int use_dgamouse = -1; | ||
39 | |||
40 | /* Check configuration to see if we should use DGA mouse */ | ||
41 | if ( use_dgamouse < 0 ) { | ||
42 | int dga_major, dga_minor; | ||
43 | int dga_flags; | ||
44 | const char *env_use_dgamouse; | ||
45 | |||
46 | use_dgamouse = 1; | ||
47 | env_use_dgamouse = SDL_getenv("SDL_VIDEO_X11_DGAMOUSE"); | ||
48 | if ( env_use_dgamouse ) { | ||
49 | use_dgamouse = SDL_atoi(env_use_dgamouse); | ||
50 | } | ||
51 | /* Check for buggy X servers */ | ||
52 | if ( use_dgamouse && BUGGY_XFREE86(==, 4000) ) { | ||
53 | use_dgamouse = 0; | ||
54 | } | ||
55 | if ( !use_dgamouse || !local_X11 || | ||
56 | !SDL_NAME(XF86DGAQueryExtension)(SDL_Display, &dga_event, &dga_error) || | ||
57 | !SDL_NAME(XF86DGAQueryVersion)(SDL_Display, &dga_major, &dga_minor) || | ||
58 | !SDL_NAME(XF86DGAQueryDirectVideo)(SDL_Display, SDL_Screen, &dga_flags) || | ||
59 | !(dga_flags & XF86DGADirectPresent) ) { | ||
60 | use_dgamouse = 0; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | if ( use_dgamouse && !(using_dga & DGA_MOUSE) ) { | ||
65 | if ( SDL_NAME(XF86DGADirectVideo)(SDL_Display, SDL_Screen, XF86DGADirectMouse) ) { | ||
66 | using_dga |= DGA_MOUSE; | ||
67 | } | ||
68 | } | ||
69 | #endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */ | ||
70 | } | ||
71 | |||
72 | /* Argh. Glide resets DGA mouse mode when it makes the context current! */ | ||
73 | void X11_CheckDGAMouse(_THIS) | ||
74 | { | ||
75 | #if SDL_VIDEO_DRIVER_X11_DGAMOUSE | ||
76 | if ( using_dga & DGA_MOUSE ) { | ||
77 | SDL_NAME(XF86DGADirectVideo)(SDL_Display,SDL_Screen,XF86DGADirectMouse); | ||
78 | } | ||
79 | #endif | ||
80 | } | ||
81 | |||
82 | void X11_DisableDGAMouse(_THIS) | ||
83 | { | ||
84 | #if SDL_VIDEO_DRIVER_X11_DGAMOUSE | ||
85 | if ( using_dga & DGA_MOUSE ) { | ||
86 | SDL_NAME(XF86DGADirectVideo)(SDL_Display, SDL_Screen, 0); | ||
87 | using_dga &= ~DGA_MOUSE; | ||
88 | } | ||
89 | #endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */ | ||
90 | } | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11dga_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11dga_c.h deleted file mode 100644 index a57511c893..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11dga_c.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_x11video.h" | ||
25 | |||
26 | /* Different DGA access states */ | ||
27 | #define DGA_GRAPHICS 0x01 | ||
28 | #define DGA_KEYBOARD 0x02 | ||
29 | #define DGA_MOUSE 0x04 | ||
30 | |||
31 | extern void X11_EnableDGAMouse(_THIS); | ||
32 | extern void X11_CheckDGAMouse(_THIS); | ||
33 | extern void X11_DisableDGAMouse(_THIS); | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11dyn.c b/apps/plugins/sdl/src/video/x11/SDL_x11dyn.c deleted file mode 100644 index 7058addfa8..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11dyn.c +++ /dev/null | |||
@@ -1,222 +0,0 @@ | |||
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 | |||
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 | |||
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 | |||
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. */ | ||
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 | } else { | ||
204 | SDL_X11_UnloadSymbols(); /* in case something got loaded... */ | ||
205 | rc = 0; | ||
206 | } | ||
207 | } | ||
208 | #else | ||
209 | #if DEBUG_DYNAMIC_X11 | ||
210 | printf("X11: No dynamic X11 support in this build of SDL.\n"); | ||
211 | #endif | ||
212 | #ifdef X_HAVE_UTF8_STRING | ||
213 | pXCreateIC = XCreateIC; | ||
214 | pXGetICValues = XGetICValues; | ||
215 | #endif | ||
216 | #endif | ||
217 | |||
218 | return rc; | ||
219 | } | ||
220 | |||
221 | /* end of SDL_x11dyn.c ... */ | ||
222 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11dyn.h b/apps/plugins/sdl/src/video/x11/SDL_x11dyn.h deleted file mode 100644 index c2ff82a727..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11dyn.h +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
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 | #ifndef _SDL_x11dyn_h | ||
25 | #define _SDL_x11dyn_h | ||
26 | |||
27 | #include <X11/Xlib.h> | ||
28 | #include <X11/Xutil.h> | ||
29 | #include <X11/Xatom.h> | ||
30 | |||
31 | /* Apparently some X11 systems can't include this multiple times... */ | ||
32 | #ifndef SDL_INCLUDED_XLIBINT_H | ||
33 | #define SDL_INCLUDED_XLIBINT_H 1 | ||
34 | #include <X11/Xlibint.h> | ||
35 | #endif | ||
36 | |||
37 | #include <X11/Xproto.h> | ||
38 | |||
39 | #include "../Xext/extensions/Xext.h" | ||
40 | #include "../Xext/extensions/extutil.h" | ||
41 | |||
42 | #ifndef NO_SHARED_MEMORY | ||
43 | #include <sys/ipc.h> | ||
44 | #include <sys/shm.h> | ||
45 | #include <X11/extensions/XShm.h> | ||
46 | #endif | ||
47 | |||
48 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
49 | #include <X11/extensions/Xrandr.h> | ||
50 | #endif | ||
51 | |||
52 | /* | ||
53 | * When using the "dynamic X11" functionality, we duplicate all the Xlib | ||
54 | * symbols that would be referenced by SDL inside of SDL itself. | ||
55 | * These duplicated symbols just serve as passthroughs to the functions | ||
56 | * in Xlib, that was dynamically loaded. | ||
57 | * | ||
58 | * This allows us to use Xlib as-is when linking against it directly, but | ||
59 | * also handles all the strange cases where there was code in the Xlib | ||
60 | * headers that may or may not exist or vary on a given platform. | ||
61 | */ | ||
62 | #ifdef __cplusplus | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | /* evil function signatures... */ | ||
67 | typedef Bool (*SDL_X11_XESetWireToEventRetType)(Display*,XEvent*,xEvent*); | ||
68 | typedef int (*SDL_X11_XSynchronizeRetType)(Display*); | ||
69 | typedef Status (*SDL_X11_XESetEventToWireRetType)(Display*,XEvent*,xEvent*); | ||
70 | |||
71 | int SDL_X11_LoadSymbols(void); | ||
72 | void SDL_X11_UnloadSymbols(void); | ||
73 | |||
74 | /* That's really annoying...make this a function pointer no matter what. */ | ||
75 | #ifdef X_HAVE_UTF8_STRING | ||
76 | extern XIC (*pXCreateIC)(XIM,...); | ||
77 | extern char *(*pXGetICValues)(XIC, ...); | ||
78 | #endif | ||
79 | |||
80 | /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ | ||
81 | #define SDL_X11_MODULE(modname) extern int SDL_X11_HAVE_##modname; | ||
82 | #define SDL_X11_SYM(rc,fn,params,args,ret) | ||
83 | #include "SDL_x11sym.h" | ||
84 | #undef SDL_X11_MODULE | ||
85 | #undef SDL_X11_SYM | ||
86 | |||
87 | |||
88 | #ifdef __cplusplus | ||
89 | } | ||
90 | #endif | ||
91 | |||
92 | #endif /* !defined _SDL_x11dyn_h */ | ||
93 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11events.c b/apps/plugins/sdl/src/video/x11/SDL_x11events.c deleted file mode 100644 index 559a001486..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11events.c +++ /dev/null | |||
@@ -1,1414 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Handle the event stream, converting X11 events into SDL events */ | ||
25 | |||
26 | #include <setjmp.h> | ||
27 | #include <X11/Xlib.h> | ||
28 | #include <X11/Xutil.h> | ||
29 | #include <X11/keysym.h> | ||
30 | #ifdef __SVR4 | ||
31 | #include <X11/Sunkeysym.h> | ||
32 | #endif | ||
33 | #include <sys/types.h> | ||
34 | #include <sys/time.h> | ||
35 | #include <unistd.h> | ||
36 | |||
37 | #include "SDL_timer.h" | ||
38 | #include "SDL_syswm.h" | ||
39 | #include "../SDL_sysvideo.h" | ||
40 | #include "../../events/SDL_sysevents.h" | ||
41 | #include "../../events/SDL_events_c.h" | ||
42 | #include "SDL_x11video.h" | ||
43 | #include "SDL_x11dga_c.h" | ||
44 | #include "SDL_x11modes_c.h" | ||
45 | #include "SDL_x11image_c.h" | ||
46 | #include "SDL_x11gamma_c.h" | ||
47 | #include "SDL_x11wm_c.h" | ||
48 | #include "SDL_x11mouse_c.h" | ||
49 | #include "SDL_x11events_c.h" | ||
50 | |||
51 | |||
52 | /* Define this if you want to debug X11 events */ | ||
53 | /*#define DEBUG_XEVENTS*/ | ||
54 | |||
55 | /* The translation tables from an X11 keysym to a SDL keysym */ | ||
56 | static SDLKey ODD_keymap[256]; | ||
57 | static SDLKey MISC_keymap[256]; | ||
58 | SDLKey X11_TranslateKeycode(Display *display, KeyCode kc); | ||
59 | |||
60 | /* | ||
61 | Pending resize target for ConfigureNotify (so outdated events don't | ||
62 | cause inappropriate resize events) | ||
63 | */ | ||
64 | int X11_PendingConfigureNotifyWidth = -1; | ||
65 | int X11_PendingConfigureNotifyHeight = -1; | ||
66 | |||
67 | #ifdef X_HAVE_UTF8_STRING | ||
68 | Uint32 Utf8ToUcs4(const Uint8 *utf8) | ||
69 | { | ||
70 | Uint32 c; | ||
71 | int i = 1; | ||
72 | int noOctets = 0; | ||
73 | int firstOctetMask = 0; | ||
74 | unsigned char firstOctet = utf8[0]; | ||
75 | if (firstOctet < 0x80) { | ||
76 | /* | ||
77 | Characters in the range: | ||
78 | 00000000 to 01111111 (ASCII Range) | ||
79 | are stored in one octet: | ||
80 | 0xxxxxxx (The same as its ASCII representation) | ||
81 | The least 6 significant bits of the first octet is the most 6 significant nonzero bits | ||
82 | of the UCS4 representation. | ||
83 | */ | ||
84 | noOctets = 1; | ||
85 | firstOctetMask = 0x7F; /* 0(1111111) - The most significant bit is ignored */ | ||
86 | } else if ((firstOctet & 0xE0) /* get the most 3 significant bits by AND'ing with 11100000 */ | ||
87 | == 0xC0 ) { /* see if those 3 bits are 110. If so, the char is in this range */ | ||
88 | /* | ||
89 | Characters in the range: | ||
90 | 00000000 10000000 to 00000111 11111111 | ||
91 | are stored in two octets: | ||
92 | 110xxxxx 10xxxxxx | ||
93 | The least 5 significant bits of the first octet is the most 5 significant nonzero bits | ||
94 | of the UCS4 representation. | ||
95 | */ | ||
96 | noOctets = 2; | ||
97 | firstOctetMask = 0x1F; /* 000(11111) - The most 3 significant bits are ignored */ | ||
98 | } else if ((firstOctet & 0xF0) /* get the most 4 significant bits by AND'ing with 11110000 */ | ||
99 | == 0xE0) { /* see if those 4 bits are 1110. If so, the char is in this range */ | ||
100 | /* | ||
101 | Characters in the range: | ||
102 | 00001000 00000000 to 11111111 11111111 | ||
103 | are stored in three octets: | ||
104 | 1110xxxx 10xxxxxx 10xxxxxx | ||
105 | The least 4 significant bits of the first octet is the most 4 significant nonzero bits | ||
106 | of the UCS4 representation. | ||
107 | */ | ||
108 | noOctets = 3; | ||
109 | firstOctetMask = 0x0F; /* 0000(1111) - The most 4 significant bits are ignored */ | ||
110 | } else if ((firstOctet & 0xF8) /* get the most 5 significant bits by AND'ing with 11111000 */ | ||
111 | == 0xF0) { /* see if those 5 bits are 11110. If so, the char is in this range */ | ||
112 | /* | ||
113 | Characters in the range: | ||
114 | 00000001 00000000 00000000 to 00011111 11111111 11111111 | ||
115 | are stored in four octets: | ||
116 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
117 | The least 3 significant bits of the first octet is the most 3 significant nonzero bits | ||
118 | of the UCS4 representation. | ||
119 | */ | ||
120 | noOctets = 4; | ||
121 | firstOctetMask = 0x07; /* 11110(111) - The most 5 significant bits are ignored */ | ||
122 | } else if ((firstOctet & 0xFC) /* get the most 6 significant bits by AND'ing with 11111100 */ | ||
123 | == 0xF8) { /* see if those 6 bits are 111110. If so, the char is in this range */ | ||
124 | /* | ||
125 | Characters in the range: | ||
126 | 00000000 00100000 00000000 00000000 to | ||
127 | 00000011 11111111 11111111 11111111 | ||
128 | are stored in five octets: | ||
129 | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
130 | The least 2 significant bits of the first octet is the most 2 significant nonzero bits | ||
131 | of the UCS4 representation. | ||
132 | */ | ||
133 | noOctets = 5; | ||
134 | firstOctetMask = 0x03; /* 111110(11) - The most 6 significant bits are ignored */ | ||
135 | } else if ((firstOctet & 0xFE) /* get the most 7 significant bits by AND'ing with 11111110 */ | ||
136 | == 0xFC) { /* see if those 7 bits are 1111110. If so, the char is in this range */ | ||
137 | /* | ||
138 | Characters in the range: | ||
139 | 00000100 00000000 00000000 00000000 to | ||
140 | 01111111 11111111 11111111 11111111 | ||
141 | are stored in six octets: | ||
142 | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
143 | The least significant bit of the first octet is the most significant nonzero bit | ||
144 | of the UCS4 representation. | ||
145 | */ | ||
146 | noOctets = 6; | ||
147 | firstOctetMask = 0x01; /* 1111110(1) - The most 7 significant bits are ignored */ | ||
148 | } else | ||
149 | return 0; /* The given chunk is not a valid UTF-8 encoded Unicode character */ | ||
150 | |||
151 | /* | ||
152 | The least noOctets significant bits of the first octet is the most 2 significant nonzero bits | ||
153 | of the UCS4 representation. | ||
154 | The first 6 bits of the UCS4 representation is the least 8-noOctets-1 significant bits of | ||
155 | firstOctet if the character is not ASCII. If so, it's the least 7 significant bits of firstOctet. | ||
156 | This done by AND'ing firstOctet with its mask to trim the bits used for identifying the | ||
157 | number of continuing octets (if any) and leave only the free bits (the x's) | ||
158 | Sample: | ||
159 | 1-octet: 0xxxxxxx & 01111111 = 0xxxxxxx | ||
160 | 2-octets: 110xxxxx & 00011111 = 000xxxxx | ||
161 | */ | ||
162 | c = firstOctet & firstOctetMask; | ||
163 | |||
164 | /* Now, start filling c.ucs4 with the bits from the continuing octets from utf8. */ | ||
165 | for (i = 1; i < noOctets; i++) { | ||
166 | /* A valid continuing octet is of the form 10xxxxxx */ | ||
167 | if ((utf8[i] & 0xC0) /* get the most 2 significant bits by AND'ing with 11000000 */ | ||
168 | != 0x80) /* see if those 2 bits are 10. If not, the is a malformed sequence. */ | ||
169 | /*The given chunk is a partial sequence at the end of a string that could | ||
170 | begin a valid character */ | ||
171 | return 0; | ||
172 | |||
173 | /* Make room for the next 6-bits */ | ||
174 | c <<= 6; | ||
175 | |||
176 | /* | ||
177 | Take only the least 6 significance bits of the current octet (utf8[i]) and fill the created room | ||
178 | of c.ucs4 with them. | ||
179 | This done by AND'ing utf8[i] with 00111111 and the OR'ing the result with c.ucs4. | ||
180 | */ | ||
181 | c |= utf8[i] & 0x3F; | ||
182 | } | ||
183 | return c; | ||
184 | } | ||
185 | |||
186 | /* Given a UTF-8 encoded string pointed to by utf8 of length length in | ||
187 | bytes, returns the corresponding UTF-16 encoded string in the | ||
188 | buffer pointed to by utf16. The maximum number of UTF-16 encoding | ||
189 | units (i.e., Unit16s) allowed in the buffer is specified in | ||
190 | utf16_max_length. The return value is the number of UTF-16 | ||
191 | encoding units placed in the output buffer pointed to by utf16. | ||
192 | |||
193 | In case of an error, -1 is returned, leaving some unusable partial | ||
194 | results in the output buffer. | ||
195 | |||
196 | The caller must estimate the size of utf16 buffer by itself before | ||
197 | calling this function. Insufficient output buffer is considered as | ||
198 | an error, and once an error occured, this function doesn't give any | ||
199 | clue how large the result will be. | ||
200 | |||
201 | The error cases include following: | ||
202 | |||
203 | - Invalid byte sequences were in the input UTF-8 bytes. The caller | ||
204 | has no way to know what point in the input buffer was the | ||
205 | errornous byte. | ||
206 | |||
207 | - The input contained a character (a valid UTF-8 byte sequence) | ||
208 | whose scalar value exceeded the range that UTF-16 can represent | ||
209 | (i.e., characters whose Unicode scalar value above 0x110000). | ||
210 | |||
211 | - The output buffer has no enough space to hold entire utf16 data. | ||
212 | |||
213 | Please note: | ||
214 | |||
215 | - '\0'-termination is not assumed both on the input UTF-8 string | ||
216 | and on the output UTF-16 string; any legal zero byte in the input | ||
217 | UTF-8 string will be converted to a 16-bit zero in output. As a | ||
218 | side effect, the last UTF-16 encoding unit stored in the output | ||
219 | buffer will have a non-zero value if the input UTF-8 was not | ||
220 | '\0'-terminated. | ||
221 | |||
222 | - UTF-8 aliases are *not* considered as an error. They are | ||
223 | converted to UTF-16. For example, 0xC0 0xA0, 0xE0 0x80 0xA0, | ||
224 | and 0xF0 0x80 0x80 0xA0 are all mapped to a single UTF-16 | ||
225 | encoding unit 0x0020. | ||
226 | |||
227 | - Three byte UTF-8 sequences whose value corresponds to a surrogate | ||
228 | code or other reserved scalar value are not considered as an | ||
229 | error either. They may cause an invalid UTF-16 data (e.g., those | ||
230 | containing unpaired surrogates). | ||
231 | |||
232 | */ | ||
233 | |||
234 | static int Utf8ToUtf16(const Uint8 *utf8, const int utf8_length, Uint16 *utf16, const int utf16_max_length) { | ||
235 | |||
236 | /* p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. */ | ||
237 | Uint16 *p = utf16; | ||
238 | Uint16 const *const max_ptr = utf16 + utf16_max_length; | ||
239 | |||
240 | /* end_of_input points to the last byte of input as opposed to the next to the last byte. */ | ||
241 | Uint8 const *const end_of_input = utf8 + utf8_length - 1; | ||
242 | |||
243 | while (utf8 <= end_of_input) { | ||
244 | Uint8 const c = *utf8; | ||
245 | if (p >= max_ptr) { | ||
246 | /* No more output space. */ | ||
247 | return -1; | ||
248 | } | ||
249 | if (c < 0x80) { | ||
250 | /* One byte ASCII. */ | ||
251 | *p++ = c; | ||
252 | utf8 += 1; | ||
253 | } else if (c < 0xC0) { | ||
254 | /* Follower byte without preceeding leader bytes. */ | ||
255 | return -1; | ||
256 | } else if (c < 0xE0) { | ||
257 | /* Two byte sequence. We need one follower byte. */ | ||
258 | if (end_of_input - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) { | ||
259 | return -1; | ||
260 | } | ||
261 | *p++ = (Uint16)(0xCF80 + (c << 6) + utf8[1]); | ||
262 | utf8 += 2; | ||
263 | } else if (c < 0xF0) { | ||
264 | /* Three byte sequence. We need two follower byte. */ | ||
265 | if (end_of_input - utf8 < 2 || (((utf8[1] ^ 0x80) | (utf8[2] ^ 0x80)) & 0xC0)) { | ||
266 | return -1; | ||
267 | } | ||
268 | *p++ = (Uint16)(0xDF80 + (c << 12) + (utf8[1] << 6) + utf8[2]); | ||
269 | utf8 += 3; | ||
270 | } else if (c < 0xF8) { | ||
271 | int plane; | ||
272 | /* Four byte sequence. We need three follower bytes. */ | ||
273 | if (end_of_input - utf8 < 3 || (((utf8[1] ^ 0x80) | (utf8[2] ^0x80) | (utf8[3] ^ 0x80)) & 0xC0)) { | ||
274 | return -1; | ||
275 | } | ||
276 | plane = (-0xC8 + (c << 2) + (utf8[1] >> 4)); | ||
277 | if (plane == 0) { | ||
278 | /* This four byte sequence is an alias that | ||
279 | corresponds to a Unicode scalar value in BMP. | ||
280 | It fits in an UTF-16 encoding unit. */ | ||
281 | *p++ = (Uint16)(0xDF80 + (utf8[1] << 12) + (utf8[2] << 6) + utf8[3]); | ||
282 | } else if (plane <= 16) { | ||
283 | /* This is a legal four byte sequence that corresponds to a surrogate pair. */ | ||
284 | if (p + 1 >= max_ptr) { | ||
285 | /* No enough space on the output buffer for the pair. */ | ||
286 | return -1; | ||
287 | } | ||
288 | *p++ = (Uint16)(0xE5B8 + (c << 8) + (utf8[1] << 2) + (utf8[2] >> 4)); | ||
289 | *p++ = (Uint16)(0xDB80 + ((utf8[2] & 0x0F) << 6) + utf8[3]); | ||
290 | } else { | ||
291 | /* This four byte sequence is out of UTF-16 code space. */ | ||
292 | return -1; | ||
293 | } | ||
294 | utf8 += 4; | ||
295 | } else { | ||
296 | /* Longer sequence or unused byte. */ | ||
297 | return -1; | ||
298 | } | ||
299 | } | ||
300 | return p - utf16; | ||
301 | } | ||
302 | |||
303 | #endif | ||
304 | |||
305 | /* Check to see if this is a repeated key. | ||
306 | (idea shamelessly lifted from GII -- thanks guys! :) | ||
307 | */ | ||
308 | static int X11_KeyRepeat(Display *display, XEvent *event) | ||
309 | { | ||
310 | XEvent peekevent; | ||
311 | int repeated; | ||
312 | |||
313 | repeated = 0; | ||
314 | if ( XPending(display) ) { | ||
315 | XPeekEvent(display, &peekevent); | ||
316 | if ( (peekevent.type == KeyPress) && | ||
317 | (peekevent.xkey.keycode == event->xkey.keycode) && | ||
318 | ((peekevent.xkey.time-event->xkey.time) < 2) ) { | ||
319 | repeated = 1; | ||
320 | XNextEvent(display, &peekevent); | ||
321 | } | ||
322 | } | ||
323 | return(repeated); | ||
324 | } | ||
325 | |||
326 | /* Note: The X server buffers and accumulates mouse motion events, so | ||
327 | the motion event generated by the warp may not appear exactly as we | ||
328 | expect it to. We work around this (and improve performance) by only | ||
329 | warping the pointer when it reaches the edge, and then wait for it. | ||
330 | */ | ||
331 | #define MOUSE_FUDGE_FACTOR 8 | ||
332 | |||
333 | static __inline__ int X11_WarpedMotion(_THIS, XEvent *xevent) | ||
334 | { | ||
335 | int w, h, i; | ||
336 | int deltax, deltay; | ||
337 | int posted; | ||
338 | |||
339 | w = SDL_VideoSurface->w; | ||
340 | h = SDL_VideoSurface->h; | ||
341 | deltax = xevent->xmotion.x - mouse_last.x; | ||
342 | deltay = xevent->xmotion.y - mouse_last.y; | ||
343 | #ifdef DEBUG_MOTION | ||
344 | printf("Warped mouse motion: %d,%d\n", deltax, deltay); | ||
345 | #endif | ||
346 | mouse_last.x = xevent->xmotion.x; | ||
347 | mouse_last.y = xevent->xmotion.y; | ||
348 | posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay); | ||
349 | |||
350 | if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) || | ||
351 | (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) || | ||
352 | (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) || | ||
353 | (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) { | ||
354 | /* Get the events that have accumulated */ | ||
355 | while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) { | ||
356 | deltax = xevent->xmotion.x - mouse_last.x; | ||
357 | deltay = xevent->xmotion.y - mouse_last.y; | ||
358 | #ifdef DEBUG_MOTION | ||
359 | printf("Extra mouse motion: %d,%d\n", deltax, deltay); | ||
360 | #endif | ||
361 | mouse_last.x = xevent->xmotion.x; | ||
362 | mouse_last.y = xevent->xmotion.y; | ||
363 | posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay); | ||
364 | } | ||
365 | mouse_last.x = w/2; | ||
366 | mouse_last.y = h/2; | ||
367 | XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, | ||
368 | mouse_last.x, mouse_last.y); | ||
369 | for ( i=0; i<10; ++i ) { | ||
370 | XMaskEvent(SDL_Display, PointerMotionMask, xevent); | ||
371 | if ( (xevent->xmotion.x > | ||
372 | (mouse_last.x-MOUSE_FUDGE_FACTOR)) && | ||
373 | (xevent->xmotion.x < | ||
374 | (mouse_last.x+MOUSE_FUDGE_FACTOR)) && | ||
375 | (xevent->xmotion.y > | ||
376 | (mouse_last.y-MOUSE_FUDGE_FACTOR)) && | ||
377 | (xevent->xmotion.y < | ||
378 | (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) { | ||
379 | break; | ||
380 | } | ||
381 | #ifdef DEBUG_XEVENTS | ||
382 | printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y); | ||
383 | #endif | ||
384 | } | ||
385 | #ifdef DEBUG_XEVENTS | ||
386 | if ( i == 10 ) { | ||
387 | printf("Warning: didn't detect mouse warp motion\n"); | ||
388 | } | ||
389 | #endif | ||
390 | } | ||
391 | return(posted); | ||
392 | } | ||
393 | |||
394 | static int X11_DispatchEvent(_THIS) | ||
395 | { | ||
396 | int posted; | ||
397 | XEvent xevent; | ||
398 | |||
399 | SDL_memset(&xevent, '\0', sizeof (XEvent)); /* valgrind fix. --ryan. */ | ||
400 | XNextEvent(SDL_Display, &xevent); | ||
401 | |||
402 | /* Discard KeyRelease and KeyPress events generated by auto-repeat. | ||
403 | We need to do it before passing event to XFilterEvent. Otherwise, | ||
404 | KeyRelease aware IMs are confused... */ | ||
405 | if ( xevent.type == KeyRelease | ||
406 | && X11_KeyRepeat(SDL_Display, &xevent) ) { | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | #ifdef X_HAVE_UTF8_STRING | ||
411 | /* If we are translating with IM, we need to pass all events | ||
412 | to XFilterEvent, and discard those filtered events immediately. */ | ||
413 | if ( SDL_TranslateUNICODE | ||
414 | && SDL_IM != NULL | ||
415 | && XFilterEvent(&xevent, None) ) { | ||
416 | return 0; | ||
417 | } | ||
418 | #endif | ||
419 | |||
420 | posted = 0; | ||
421 | switch (xevent.type) { | ||
422 | |||
423 | /* Gaining mouse coverage? */ | ||
424 | case EnterNotify: { | ||
425 | #ifdef DEBUG_XEVENTS | ||
426 | printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y); | ||
427 | if ( xevent.xcrossing.mode == NotifyGrab ) | ||
428 | printf("Mode: NotifyGrab\n"); | ||
429 | if ( xevent.xcrossing.mode == NotifyUngrab ) | ||
430 | printf("Mode: NotifyUngrab\n"); | ||
431 | #endif | ||
432 | if ( this->input_grab == SDL_GRAB_OFF ) { | ||
433 | posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | ||
434 | } | ||
435 | posted = SDL_PrivateMouseMotion(0, 0, | ||
436 | xevent.xcrossing.x, | ||
437 | xevent.xcrossing.y); | ||
438 | } | ||
439 | break; | ||
440 | |||
441 | /* Losing mouse coverage? */ | ||
442 | case LeaveNotify: { | ||
443 | #ifdef DEBUG_XEVENTS | ||
444 | printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y); | ||
445 | if ( xevent.xcrossing.mode == NotifyGrab ) | ||
446 | printf("Mode: NotifyGrab\n"); | ||
447 | if ( xevent.xcrossing.mode == NotifyUngrab ) | ||
448 | printf("Mode: NotifyUngrab\n"); | ||
449 | #endif | ||
450 | if ( (xevent.xcrossing.mode != NotifyGrab) && | ||
451 | (xevent.xcrossing.mode != NotifyUngrab) && | ||
452 | (xevent.xcrossing.detail != NotifyInferior) ) { | ||
453 | if ( this->input_grab == SDL_GRAB_OFF ) { | ||
454 | posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); | ||
455 | } else { | ||
456 | posted = SDL_PrivateMouseMotion(0, 0, | ||
457 | xevent.xcrossing.x, | ||
458 | xevent.xcrossing.y); | ||
459 | } | ||
460 | } | ||
461 | } | ||
462 | break; | ||
463 | |||
464 | /* Gaining input focus? */ | ||
465 | case FocusIn: { | ||
466 | #ifdef DEBUG_XEVENTS | ||
467 | printf("FocusIn!\n"); | ||
468 | #endif | ||
469 | posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); | ||
470 | |||
471 | #ifdef X_HAVE_UTF8_STRING | ||
472 | if ( SDL_IC != NULL ) { | ||
473 | XSetICFocus(SDL_IC); | ||
474 | } | ||
475 | #endif | ||
476 | /* Queue entry into fullscreen mode */ | ||
477 | switch_waiting = 0x01 | SDL_FULLSCREEN; | ||
478 | switch_time = SDL_GetTicks() + 1500; | ||
479 | } | ||
480 | break; | ||
481 | |||
482 | /* Losing input focus? */ | ||
483 | case FocusOut: { | ||
484 | #ifdef DEBUG_XEVENTS | ||
485 | printf("FocusOut!\n"); | ||
486 | #endif | ||
487 | posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); | ||
488 | |||
489 | #ifdef X_HAVE_UTF8_STRING | ||
490 | if ( SDL_IC != NULL ) { | ||
491 | XUnsetICFocus(SDL_IC); | ||
492 | } | ||
493 | #endif | ||
494 | /* Queue leaving fullscreen mode */ | ||
495 | switch_waiting = 0x01; | ||
496 | switch_time = SDL_GetTicks() + 200; | ||
497 | } | ||
498 | break; | ||
499 | |||
500 | #ifdef X_HAVE_UTF8_STRING | ||
501 | /* Some IM requires MappingNotify to be passed to | ||
502 | XRefreshKeyboardMapping by the app. */ | ||
503 | case MappingNotify: { | ||
504 | XRefreshKeyboardMapping(&xevent.xmapping); | ||
505 | } | ||
506 | break; | ||
507 | #endif /* X_HAVE_UTF8_STRING */ | ||
508 | |||
509 | /* Generated upon EnterWindow and FocusIn */ | ||
510 | case KeymapNotify: { | ||
511 | #ifdef DEBUG_XEVENTS | ||
512 | printf("KeymapNotify!\n"); | ||
513 | #endif | ||
514 | X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector); | ||
515 | } | ||
516 | break; | ||
517 | |||
518 | /* Mouse motion? */ | ||
519 | case MotionNotify: { | ||
520 | if ( SDL_VideoSurface ) { | ||
521 | if ( mouse_relative ) { | ||
522 | if ( using_dga & DGA_MOUSE ) { | ||
523 | #ifdef DEBUG_MOTION | ||
524 | printf("DGA motion: %d,%d\n", xevent.xmotion.x_root, xevent.xmotion.y_root); | ||
525 | #endif | ||
526 | posted = SDL_PrivateMouseMotion(0, 1, | ||
527 | xevent.xmotion.x_root, | ||
528 | xevent.xmotion.y_root); | ||
529 | } else { | ||
530 | posted = X11_WarpedMotion(this,&xevent); | ||
531 | } | ||
532 | } else { | ||
533 | #ifdef DEBUG_MOTION | ||
534 | printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y); | ||
535 | #endif | ||
536 | posted = SDL_PrivateMouseMotion(0, 0, | ||
537 | xevent.xmotion.x, | ||
538 | xevent.xmotion.y); | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | break; | ||
543 | |||
544 | /* Mouse button press? */ | ||
545 | case ButtonPress: { | ||
546 | posted = SDL_PrivateMouseButton(SDL_PRESSED, | ||
547 | xevent.xbutton.button, 0, 0); | ||
548 | } | ||
549 | break; | ||
550 | |||
551 | /* Mouse button release? */ | ||
552 | case ButtonRelease: { | ||
553 | posted = SDL_PrivateMouseButton(SDL_RELEASED, | ||
554 | xevent.xbutton.button, 0, 0); | ||
555 | } | ||
556 | break; | ||
557 | |||
558 | /* Key press? */ | ||
559 | case KeyPress: { | ||
560 | SDL_keysym keysym; | ||
561 | KeyCode keycode = xevent.xkey.keycode; | ||
562 | |||
563 | #ifdef DEBUG_XEVENTS | ||
564 | printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); | ||
565 | #endif | ||
566 | /* If we're not doing translation, we're done! */ | ||
567 | if ( !SDL_TranslateUNICODE ) { | ||
568 | /* Get the translated SDL virtual keysym and put it on the queue.*/ | ||
569 | keysym.scancode = keycode; | ||
570 | keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); | ||
571 | keysym.mod = KMOD_NONE; | ||
572 | keysym.unicode = 0; | ||
573 | posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | ||
574 | break; | ||
575 | } | ||
576 | |||
577 | /* Look up the translated value for the key event */ | ||
578 | #ifdef X_HAVE_UTF8_STRING | ||
579 | if ( SDL_IC != NULL ) { | ||
580 | Status status; | ||
581 | KeySym xkeysym; | ||
582 | int i; | ||
583 | /* A UTF-8 character can be at most 6 bytes */ | ||
584 | /* ... It's true, but Xutf8LookupString can | ||
585 | return more than one characters. Moreover, | ||
586 | the spec. put no upper bound, so we should | ||
587 | be ready for longer strings. */ | ||
588 | char keybuf[32]; | ||
589 | char *keydata = keybuf; | ||
590 | int count; | ||
591 | Uint16 utf16buf[32]; | ||
592 | Uint16 *utf16data = utf16buf; | ||
593 | int utf16size; | ||
594 | int utf16length; | ||
595 | |||
596 | count = Xutf8LookupString(SDL_IC, &xevent.xkey, keydata, sizeof(keybuf), &xkeysym, &status); | ||
597 | if (XBufferOverflow == status) { | ||
598 | /* The IM has just generated somewhat long | ||
599 | string. We need a longer buffer in this | ||
600 | case. */ | ||
601 | keydata = SDL_malloc(count); | ||
602 | if ( keydata == NULL ) { | ||
603 | SDL_OutOfMemory(); | ||
604 | break; | ||
605 | } | ||
606 | count = Xutf8LookupString(SDL_IC, &xevent.xkey, keydata, count, &xkeysym, &status); | ||
607 | } | ||
608 | |||
609 | switch (status) { | ||
610 | |||
611 | case XBufferOverflow: { | ||
612 | /* Oops! We have allocated the bytes as | ||
613 | requested by Xutf8LookupString, so the | ||
614 | length of the buffer must be | ||
615 | sufficient. This case should never | ||
616 | happen! */ | ||
617 | SDL_SetError("Xutf8LookupString indicated a double buffer overflow!"); | ||
618 | break; | ||
619 | } | ||
620 | |||
621 | case XLookupChars: | ||
622 | case XLookupBoth: { | ||
623 | if (0 == count) { | ||
624 | break; | ||
625 | } | ||
626 | |||
627 | /* We got a converted string from IM. Make | ||
628 | sure to deliver all characters to the | ||
629 | application as SDL events. Note that | ||
630 | an SDL event can only carry one UTF-16 | ||
631 | encoding unit, and a surrogate pair is | ||
632 | delivered as two SDL events. I guess | ||
633 | this behaviour is probably _imported_ | ||
634 | from Windows or MacOS. To do so, we need | ||
635 | to convert the UTF-8 data into UTF-16 | ||
636 | data (not UCS4/UTF-32!). We need an | ||
637 | estimate of the number of UTF-16 encoding | ||
638 | units here. The worst case is pure ASCII | ||
639 | string. Assume so. */ | ||
640 | /* In 1.3 SDL may have a text event instead, that | ||
641 | carries the whole UTF-8 string with it. */ | ||
642 | utf16size = count * sizeof(Uint16); | ||
643 | if (utf16size > sizeof(utf16buf)) { | ||
644 | utf16data = (Uint16 *) SDL_malloc(utf16size); | ||
645 | if (utf16data == NULL) { | ||
646 | SDL_OutOfMemory(); | ||
647 | break; | ||
648 | } | ||
649 | } | ||
650 | utf16length = Utf8ToUtf16((Uint8 *)keydata, count, utf16data, utf16size); | ||
651 | if (utf16length < 0) { | ||
652 | /* The keydata contained an invalid byte | ||
653 | sequence. It should be a bug of the IM | ||
654 | or Xlib... */ | ||
655 | SDL_SetError("Oops! Xutf8LookupString returned an invalid UTF-8 sequence!"); | ||
656 | break; | ||
657 | } | ||
658 | |||
659 | /* Deliver all UTF-16 encoding units. At | ||
660 | this moment, SDL event queue has a | ||
661 | fixed size (128 events), and an SDL | ||
662 | event can hold just one UTF-16 encoding | ||
663 | unit. So, if we receive more than 128 | ||
664 | UTF-16 encoding units from a commit, | ||
665 | exceeded characters will be lost. */ | ||
666 | for (i = 0; i < utf16length - 1; i++) { | ||
667 | keysym.scancode = 0; | ||
668 | keysym.sym = SDLK_UNKNOWN; | ||
669 | keysym.mod = KMOD_NONE; | ||
670 | keysym.unicode = utf16data[i]; | ||
671 | posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | ||
672 | } | ||
673 | /* The keysym for the last character carries the | ||
674 | scancode and symbol that corresponds to the X11 | ||
675 | keycode. */ | ||
676 | if (utf16length > 0) { | ||
677 | keysym.scancode = keycode; | ||
678 | keysym.sym = (keycode ? X11_TranslateKeycode(SDL_Display, keycode) : 0); | ||
679 | keysym.mod = KMOD_NONE; | ||
680 | keysym.unicode = utf16data[utf16length - 1]; | ||
681 | posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | ||
682 | } | ||
683 | break; | ||
684 | } | ||
685 | |||
686 | case XLookupKeySym: { | ||
687 | /* I'm not sure whether it is possible that | ||
688 | a zero keycode makes XLookupKeySym | ||
689 | status. What I'm sure is that a | ||
690 | combination of a zero scan code and a non | ||
691 | zero sym makes SDL_PrivateKeyboard | ||
692 | strange state... So, just discard it. | ||
693 | If this doesn't work, I'm receiving bug | ||
694 | reports, and I can know under what | ||
695 | condition this case happens. */ | ||
696 | if (keycode) { | ||
697 | keysym.scancode = keycode; | ||
698 | keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); | ||
699 | keysym.mod = KMOD_NONE; | ||
700 | keysym.unicode = 0; | ||
701 | posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | ||
702 | } | ||
703 | break; | ||
704 | } | ||
705 | |||
706 | case XLookupNone: { | ||
707 | /* IM has eaten the event. */ | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | default: | ||
712 | /* An unknown status from Xutf8LookupString. */ | ||
713 | SDL_SetError("Oops! Xutf8LookupStringreturned an unknown status"); | ||
714 | } | ||
715 | |||
716 | /* Release dynamic buffers if allocated. */ | ||
717 | if (keydata != NULL && keybuf != keydata) { | ||
718 | SDL_free(keydata); | ||
719 | } | ||
720 | if (utf16data != NULL && utf16buf != utf16data) { | ||
721 | SDL_free(utf16data); | ||
722 | } | ||
723 | } | ||
724 | else | ||
725 | #endif | ||
726 | { | ||
727 | static XComposeStatus state; | ||
728 | char keybuf[32]; | ||
729 | |||
730 | keysym.scancode = keycode; | ||
731 | keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); | ||
732 | keysym.mod = KMOD_NONE; | ||
733 | keysym.unicode = 0; | ||
734 | if ( XLookupString(&xevent.xkey, | ||
735 | keybuf, sizeof(keybuf), | ||
736 | NULL, &state) ) { | ||
737 | /* | ||
738 | * FIXME: XLookupString() may yield more than one | ||
739 | * character, so we need a mechanism to allow for | ||
740 | * this (perhaps null keypress events with a | ||
741 | * unicode value) | ||
742 | */ | ||
743 | keysym.unicode = (Uint8)keybuf[0]; | ||
744 | } | ||
745 | |||
746 | posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | ||
747 | } | ||
748 | } | ||
749 | break; | ||
750 | |||
751 | /* Key release? */ | ||
752 | case KeyRelease: { | ||
753 | SDL_keysym keysym; | ||
754 | KeyCode keycode = xevent.xkey.keycode; | ||
755 | |||
756 | if (keycode == 0) { | ||
757 | /* There should be no KeyRelease for keycode == 0, | ||
758 | since it is a notification from IM but a real | ||
759 | keystroke. */ | ||
760 | /* We need to emit some diagnostic message here. */ | ||
761 | break; | ||
762 | } | ||
763 | |||
764 | #ifdef DEBUG_XEVENTS | ||
765 | printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); | ||
766 | #endif | ||
767 | |||
768 | /* Get the translated SDL virtual keysym */ | ||
769 | keysym.scancode = keycode; | ||
770 | keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); | ||
771 | keysym.mod = KMOD_NONE; | ||
772 | keysym.unicode = 0; | ||
773 | |||
774 | posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym); | ||
775 | } | ||
776 | break; | ||
777 | |||
778 | /* Have we been iconified? */ | ||
779 | case UnmapNotify: { | ||
780 | #ifdef DEBUG_XEVENTS | ||
781 | printf("UnmapNotify!\n"); | ||
782 | #endif | ||
783 | /* If we're active, make ourselves inactive */ | ||
784 | if ( SDL_GetAppState() & SDL_APPACTIVE ) { | ||
785 | /* Swap out the gamma before we go inactive */ | ||
786 | X11_SwapVidModeGamma(this); | ||
787 | |||
788 | /* Send an internal deactivate event */ | ||
789 | posted = SDL_PrivateAppActive(0, | ||
790 | SDL_APPACTIVE|SDL_APPINPUTFOCUS); | ||
791 | } | ||
792 | } | ||
793 | break; | ||
794 | |||
795 | /* Have we been restored? */ | ||
796 | case MapNotify: { | ||
797 | #ifdef DEBUG_XEVENTS | ||
798 | printf("MapNotify!\n"); | ||
799 | #endif | ||
800 | /* If we're not active, make ourselves active */ | ||
801 | if ( !(SDL_GetAppState() & SDL_APPACTIVE) ) { | ||
802 | /* Send an internal activate event */ | ||
803 | posted = SDL_PrivateAppActive(1, SDL_APPACTIVE); | ||
804 | |||
805 | /* Now that we're active, swap the gamma back */ | ||
806 | X11_SwapVidModeGamma(this); | ||
807 | } | ||
808 | |||
809 | if ( SDL_VideoSurface && | ||
810 | (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { | ||
811 | X11_EnterFullScreen(this); | ||
812 | } else { | ||
813 | X11_GrabInputNoLock(this, this->input_grab); | ||
814 | } | ||
815 | X11_CheckMouseModeNoLock(this); | ||
816 | |||
817 | if ( SDL_VideoSurface ) { | ||
818 | X11_RefreshDisplay(this); | ||
819 | } | ||
820 | } | ||
821 | break; | ||
822 | |||
823 | /* Have we been resized or moved? */ | ||
824 | case ConfigureNotify: { | ||
825 | #ifdef DEBUG_XEVENTS | ||
826 | printf("ConfigureNotify! (resize: %dx%d)\n", xevent.xconfigure.width, xevent.xconfigure.height); | ||
827 | #endif | ||
828 | if ((X11_PendingConfigureNotifyWidth != -1) && | ||
829 | (X11_PendingConfigureNotifyHeight != -1)) { | ||
830 | if ((xevent.xconfigure.width != X11_PendingConfigureNotifyWidth) && | ||
831 | (xevent.xconfigure.height != X11_PendingConfigureNotifyHeight)) { | ||
832 | /* Event is from before the resize, so ignore. */ | ||
833 | break; | ||
834 | } | ||
835 | X11_PendingConfigureNotifyWidth = -1; | ||
836 | X11_PendingConfigureNotifyHeight = -1; | ||
837 | } | ||
838 | if ( SDL_VideoSurface ) { | ||
839 | if ((xevent.xconfigure.width != SDL_VideoSurface->w) || | ||
840 | (xevent.xconfigure.height != SDL_VideoSurface->h)) { | ||
841 | /* FIXME: Find a better fix for the bug with KDE 1.2 */ | ||
842 | if ( ! ((xevent.xconfigure.width == 32) && | ||
843 | (xevent.xconfigure.height == 32)) ) { | ||
844 | SDL_PrivateResize(xevent.xconfigure.width, | ||
845 | xevent.xconfigure.height); | ||
846 | } | ||
847 | } else { | ||
848 | /* OpenGL windows need to know about the change */ | ||
849 | if ( SDL_VideoSurface->flags & SDL_OPENGL ) { | ||
850 | SDL_PrivateExpose(); | ||
851 | } | ||
852 | } | ||
853 | } | ||
854 | } | ||
855 | break; | ||
856 | |||
857 | /* Have we been requested to quit (or another client message?) */ | ||
858 | case ClientMessage: { | ||
859 | if ( (xevent.xclient.format == 32) && | ||
860 | (xevent.xclient.data.l[0] == WM_DELETE_WINDOW) ) | ||
861 | { | ||
862 | posted = SDL_PrivateQuit(); | ||
863 | } else | ||
864 | if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { | ||
865 | SDL_SysWMmsg wmmsg; | ||
866 | |||
867 | SDL_VERSION(&wmmsg.version); | ||
868 | wmmsg.subsystem = SDL_SYSWM_X11; | ||
869 | wmmsg.event.xevent = xevent; | ||
870 | posted = SDL_PrivateSysWMEvent(&wmmsg); | ||
871 | } | ||
872 | } | ||
873 | break; | ||
874 | |||
875 | /* Do we need to refresh ourselves? */ | ||
876 | case Expose: { | ||
877 | #ifdef DEBUG_XEVENTS | ||
878 | printf("Expose (count = %d)\n", xevent.xexpose.count); | ||
879 | #endif | ||
880 | if ( SDL_VideoSurface && (xevent.xexpose.count == 0) ) { | ||
881 | X11_RefreshDisplay(this); | ||
882 | } | ||
883 | } | ||
884 | break; | ||
885 | |||
886 | default: { | ||
887 | #ifdef DEBUG_XEVENTS | ||
888 | printf("Unhandled event %d\n", xevent.type); | ||
889 | #endif | ||
890 | /* Only post the event if we're watching for it */ | ||
891 | if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { | ||
892 | SDL_SysWMmsg wmmsg; | ||
893 | |||
894 | SDL_VERSION(&wmmsg.version); | ||
895 | wmmsg.subsystem = SDL_SYSWM_X11; | ||
896 | wmmsg.event.xevent = xevent; | ||
897 | posted = SDL_PrivateSysWMEvent(&wmmsg); | ||
898 | } | ||
899 | } | ||
900 | break; | ||
901 | } | ||
902 | return(posted); | ||
903 | } | ||
904 | |||
905 | /* Ack! XPending() actually performs a blocking read if no events available */ | ||
906 | int X11_Pending(Display *display) | ||
907 | { | ||
908 | /* Flush the display connection and look to see if events are queued */ | ||
909 | XFlush(display); | ||
910 | if ( XEventsQueued(display, QueuedAlready) ) { | ||
911 | return(1); | ||
912 | } | ||
913 | |||
914 | /* More drastic measures are required -- see if X is ready to talk */ | ||
915 | { | ||
916 | static struct timeval zero_time; /* static == 0 */ | ||
917 | int x11_fd; | ||
918 | fd_set fdset; | ||
919 | |||
920 | x11_fd = ConnectionNumber(display); | ||
921 | FD_ZERO(&fdset); | ||
922 | FD_SET(x11_fd, &fdset); | ||
923 | if ( select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1 ) { | ||
924 | return(XPending(display)); | ||
925 | } | ||
926 | } | ||
927 | |||
928 | /* Oh well, nothing is ready .. */ | ||
929 | return(0); | ||
930 | } | ||
931 | |||
932 | void X11_PumpEvents(_THIS) | ||
933 | { | ||
934 | int pending; | ||
935 | |||
936 | /* Update activity every five seconds to prevent screensaver. --ryan. */ | ||
937 | if (!allow_screensaver) { | ||
938 | static Uint32 screensaverTicks; | ||
939 | Uint32 nowTicks = SDL_GetTicks(); | ||
940 | if ((nowTicks - screensaverTicks) > 5000) { | ||
941 | XResetScreenSaver(SDL_Display); | ||
942 | screensaverTicks = nowTicks; | ||
943 | } | ||
944 | } | ||
945 | |||
946 | /* Keep processing pending events */ | ||
947 | pending = 0; | ||
948 | while ( X11_Pending(SDL_Display) ) { | ||
949 | X11_DispatchEvent(this); | ||
950 | ++pending; | ||
951 | } | ||
952 | if ( switch_waiting ) { | ||
953 | Uint32 now; | ||
954 | |||
955 | now = SDL_GetTicks(); | ||
956 | if ( pending || !SDL_VideoSurface ) { | ||
957 | /* Try again later... */ | ||
958 | if ( switch_waiting & SDL_FULLSCREEN ) { | ||
959 | switch_time = now + 1500; | ||
960 | } else { | ||
961 | switch_time = now + 200; | ||
962 | } | ||
963 | } else if ( (int)(switch_time-now) <= 0 ) { | ||
964 | Uint32 go_fullscreen; | ||
965 | |||
966 | go_fullscreen = switch_waiting & SDL_FULLSCREEN; | ||
967 | switch_waiting = 0; | ||
968 | if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) { | ||
969 | if ( go_fullscreen ) { | ||
970 | X11_EnterFullScreen(this); | ||
971 | } else { | ||
972 | X11_LeaveFullScreen(this); | ||
973 | } | ||
974 | } | ||
975 | /* Handle focus in/out when grabbed */ | ||
976 | if ( go_fullscreen ) { | ||
977 | X11_GrabInputNoLock(this, this->input_grab); | ||
978 | } else { | ||
979 | X11_GrabInputNoLock(this, SDL_GRAB_OFF); | ||
980 | } | ||
981 | X11_CheckMouseModeNoLock(this); | ||
982 | } | ||
983 | } | ||
984 | } | ||
985 | |||
986 | void X11_InitKeymap(void) | ||
987 | { | ||
988 | int i; | ||
989 | |||
990 | /* Odd keys used in international keyboards */ | ||
991 | for ( i=0; i<SDL_arraysize(ODD_keymap); ++i ) | ||
992 | ODD_keymap[i] = SDLK_UNKNOWN; | ||
993 | |||
994 | /* Some of these might be mappable to an existing SDLK_ code */ | ||
995 | ODD_keymap[XK_dead_grave&0xFF] = SDLK_COMPOSE; | ||
996 | ODD_keymap[XK_dead_acute&0xFF] = SDLK_COMPOSE; | ||
997 | ODD_keymap[XK_dead_tilde&0xFF] = SDLK_COMPOSE; | ||
998 | ODD_keymap[XK_dead_macron&0xFF] = SDLK_COMPOSE; | ||
999 | ODD_keymap[XK_dead_breve&0xFF] = SDLK_COMPOSE; | ||
1000 | ODD_keymap[XK_dead_abovedot&0xFF] = SDLK_COMPOSE; | ||
1001 | ODD_keymap[XK_dead_diaeresis&0xFF] = SDLK_COMPOSE; | ||
1002 | ODD_keymap[XK_dead_abovering&0xFF] = SDLK_COMPOSE; | ||
1003 | ODD_keymap[XK_dead_doubleacute&0xFF] = SDLK_COMPOSE; | ||
1004 | ODD_keymap[XK_dead_caron&0xFF] = SDLK_COMPOSE; | ||
1005 | ODD_keymap[XK_dead_cedilla&0xFF] = SDLK_COMPOSE; | ||
1006 | ODD_keymap[XK_dead_ogonek&0xFF] = SDLK_COMPOSE; | ||
1007 | ODD_keymap[XK_dead_iota&0xFF] = SDLK_COMPOSE; | ||
1008 | ODD_keymap[XK_dead_voiced_sound&0xFF] = SDLK_COMPOSE; | ||
1009 | ODD_keymap[XK_dead_semivoiced_sound&0xFF] = SDLK_COMPOSE; | ||
1010 | ODD_keymap[XK_dead_belowdot&0xFF] = SDLK_COMPOSE; | ||
1011 | #ifdef XK_dead_hook | ||
1012 | ODD_keymap[XK_dead_hook&0xFF] = SDLK_COMPOSE; | ||
1013 | #endif | ||
1014 | #ifdef XK_dead_horn | ||
1015 | ODD_keymap[XK_dead_horn&0xFF] = SDLK_COMPOSE; | ||
1016 | #endif | ||
1017 | |||
1018 | #ifdef XK_dead_circumflex | ||
1019 | /* These X keysyms have 0xFE as the high byte */ | ||
1020 | ODD_keymap[XK_dead_circumflex&0xFF] = SDLK_CARET; | ||
1021 | #endif | ||
1022 | #ifdef XK_ISO_Level3_Shift | ||
1023 | ODD_keymap[XK_ISO_Level3_Shift&0xFF] = SDLK_MODE; /* "Alt Gr" key */ | ||
1024 | #endif | ||
1025 | |||
1026 | /* Map the miscellaneous keys */ | ||
1027 | for ( i=0; i<SDL_arraysize(MISC_keymap); ++i ) | ||
1028 | MISC_keymap[i] = SDLK_UNKNOWN; | ||
1029 | |||
1030 | /* These X keysyms have 0xFF as the high byte */ | ||
1031 | MISC_keymap[XK_BackSpace&0xFF] = SDLK_BACKSPACE; | ||
1032 | MISC_keymap[XK_Tab&0xFF] = SDLK_TAB; | ||
1033 | MISC_keymap[XK_Clear&0xFF] = SDLK_CLEAR; | ||
1034 | MISC_keymap[XK_Return&0xFF] = SDLK_RETURN; | ||
1035 | MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE; | ||
1036 | MISC_keymap[XK_Escape&0xFF] = SDLK_ESCAPE; | ||
1037 | MISC_keymap[XK_Delete&0xFF] = SDLK_DELETE; | ||
1038 | |||
1039 | MISC_keymap[XK_KP_0&0xFF] = SDLK_KP0; /* Keypad 0-9 */ | ||
1040 | MISC_keymap[XK_KP_1&0xFF] = SDLK_KP1; | ||
1041 | MISC_keymap[XK_KP_2&0xFF] = SDLK_KP2; | ||
1042 | MISC_keymap[XK_KP_3&0xFF] = SDLK_KP3; | ||
1043 | MISC_keymap[XK_KP_4&0xFF] = SDLK_KP4; | ||
1044 | MISC_keymap[XK_KP_5&0xFF] = SDLK_KP5; | ||
1045 | MISC_keymap[XK_KP_6&0xFF] = SDLK_KP6; | ||
1046 | MISC_keymap[XK_KP_7&0xFF] = SDLK_KP7; | ||
1047 | MISC_keymap[XK_KP_8&0xFF] = SDLK_KP8; | ||
1048 | MISC_keymap[XK_KP_9&0xFF] = SDLK_KP9; | ||
1049 | MISC_keymap[XK_KP_Insert&0xFF] = SDLK_KP0; | ||
1050 | MISC_keymap[XK_KP_End&0xFF] = SDLK_KP1; | ||
1051 | MISC_keymap[XK_KP_Down&0xFF] = SDLK_KP2; | ||
1052 | MISC_keymap[XK_KP_Page_Down&0xFF] = SDLK_KP3; | ||
1053 | MISC_keymap[XK_KP_Left&0xFF] = SDLK_KP4; | ||
1054 | MISC_keymap[XK_KP_Begin&0xFF] = SDLK_KP5; | ||
1055 | MISC_keymap[XK_KP_Right&0xFF] = SDLK_KP6; | ||
1056 | MISC_keymap[XK_KP_Home&0xFF] = SDLK_KP7; | ||
1057 | MISC_keymap[XK_KP_Up&0xFF] = SDLK_KP8; | ||
1058 | MISC_keymap[XK_KP_Page_Up&0xFF] = SDLK_KP9; | ||
1059 | MISC_keymap[XK_KP_Delete&0xFF] = SDLK_KP_PERIOD; | ||
1060 | MISC_keymap[XK_KP_Decimal&0xFF] = SDLK_KP_PERIOD; | ||
1061 | MISC_keymap[XK_KP_Divide&0xFF] = SDLK_KP_DIVIDE; | ||
1062 | MISC_keymap[XK_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY; | ||
1063 | MISC_keymap[XK_KP_Subtract&0xFF] = SDLK_KP_MINUS; | ||
1064 | MISC_keymap[XK_KP_Add&0xFF] = SDLK_KP_PLUS; | ||
1065 | MISC_keymap[XK_KP_Enter&0xFF] = SDLK_KP_ENTER; | ||
1066 | MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS; | ||
1067 | |||
1068 | MISC_keymap[XK_Up&0xFF] = SDLK_UP; | ||
1069 | MISC_keymap[XK_Down&0xFF] = SDLK_DOWN; | ||
1070 | MISC_keymap[XK_Right&0xFF] = SDLK_RIGHT; | ||
1071 | MISC_keymap[XK_Left&0xFF] = SDLK_LEFT; | ||
1072 | MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT; | ||
1073 | MISC_keymap[XK_Home&0xFF] = SDLK_HOME; | ||
1074 | MISC_keymap[XK_End&0xFF] = SDLK_END; | ||
1075 | MISC_keymap[XK_Page_Up&0xFF] = SDLK_PAGEUP; | ||
1076 | MISC_keymap[XK_Page_Down&0xFF] = SDLK_PAGEDOWN; | ||
1077 | |||
1078 | MISC_keymap[XK_F1&0xFF] = SDLK_F1; | ||
1079 | MISC_keymap[XK_F2&0xFF] = SDLK_F2; | ||
1080 | MISC_keymap[XK_F3&0xFF] = SDLK_F3; | ||
1081 | MISC_keymap[XK_F4&0xFF] = SDLK_F4; | ||
1082 | MISC_keymap[XK_F5&0xFF] = SDLK_F5; | ||
1083 | MISC_keymap[XK_F6&0xFF] = SDLK_F6; | ||
1084 | MISC_keymap[XK_F7&0xFF] = SDLK_F7; | ||
1085 | MISC_keymap[XK_F8&0xFF] = SDLK_F8; | ||
1086 | MISC_keymap[XK_F9&0xFF] = SDLK_F9; | ||
1087 | MISC_keymap[XK_F10&0xFF] = SDLK_F10; | ||
1088 | MISC_keymap[XK_F11&0xFF] = SDLK_F11; | ||
1089 | MISC_keymap[XK_F12&0xFF] = SDLK_F12; | ||
1090 | MISC_keymap[XK_F13&0xFF] = SDLK_F13; | ||
1091 | MISC_keymap[XK_F14&0xFF] = SDLK_F14; | ||
1092 | MISC_keymap[XK_F15&0xFF] = SDLK_F15; | ||
1093 | |||
1094 | MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK; | ||
1095 | MISC_keymap[XK_Caps_Lock&0xFF] = SDLK_CAPSLOCK; | ||
1096 | MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK; | ||
1097 | MISC_keymap[XK_Shift_R&0xFF] = SDLK_RSHIFT; | ||
1098 | MISC_keymap[XK_Shift_L&0xFF] = SDLK_LSHIFT; | ||
1099 | MISC_keymap[XK_Control_R&0xFF] = SDLK_RCTRL; | ||
1100 | MISC_keymap[XK_Control_L&0xFF] = SDLK_LCTRL; | ||
1101 | MISC_keymap[XK_Alt_R&0xFF] = SDLK_RALT; | ||
1102 | MISC_keymap[XK_Alt_L&0xFF] = SDLK_LALT; | ||
1103 | MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA; | ||
1104 | MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA; | ||
1105 | MISC_keymap[XK_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */ | ||
1106 | MISC_keymap[XK_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */ | ||
1107 | MISC_keymap[XK_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */ | ||
1108 | MISC_keymap[XK_Multi_key&0xFF] = SDLK_COMPOSE; /* Multi-key compose */ | ||
1109 | |||
1110 | MISC_keymap[XK_Help&0xFF] = SDLK_HELP; | ||
1111 | MISC_keymap[XK_Print&0xFF] = SDLK_PRINT; | ||
1112 | MISC_keymap[XK_Sys_Req&0xFF] = SDLK_SYSREQ; | ||
1113 | MISC_keymap[XK_Break&0xFF] = SDLK_BREAK; | ||
1114 | MISC_keymap[XK_Menu&0xFF] = SDLK_MENU; | ||
1115 | MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */ | ||
1116 | } | ||
1117 | |||
1118 | /* Get the translated SDL virtual keysym */ | ||
1119 | SDLKey X11_TranslateKeycode(Display *display, KeyCode kc) | ||
1120 | { | ||
1121 | KeySym xsym; | ||
1122 | SDLKey key; | ||
1123 | |||
1124 | xsym = XKeycodeToKeysym(display, kc, 0); | ||
1125 | #ifdef DEBUG_KEYS | ||
1126 | fprintf(stderr, "Translating key code %d -> 0x%.4x\n", kc, xsym); | ||
1127 | #endif | ||
1128 | key = SDLK_UNKNOWN; | ||
1129 | if ( xsym ) { | ||
1130 | switch (xsym>>8) { | ||
1131 | case 0x1005FF: | ||
1132 | #ifdef SunXK_F36 | ||
1133 | if ( xsym == SunXK_F36 ) | ||
1134 | key = SDLK_F11; | ||
1135 | #endif | ||
1136 | #ifdef SunXK_F37 | ||
1137 | if ( xsym == SunXK_F37 ) | ||
1138 | key = SDLK_F12; | ||
1139 | #endif | ||
1140 | break; | ||
1141 | case 0x00: /* Latin 1 */ | ||
1142 | key = (SDLKey)(xsym & 0xFF); | ||
1143 | break; | ||
1144 | case 0x01: /* Latin 2 */ | ||
1145 | case 0x02: /* Latin 3 */ | ||
1146 | case 0x03: /* Latin 4 */ | ||
1147 | case 0x04: /* Katakana */ | ||
1148 | case 0x05: /* Arabic */ | ||
1149 | case 0x06: /* Cyrillic */ | ||
1150 | case 0x07: /* Greek */ | ||
1151 | case 0x08: /* Technical */ | ||
1152 | case 0x0A: /* Publishing */ | ||
1153 | case 0x0C: /* Hebrew */ | ||
1154 | case 0x0D: /* Thai */ | ||
1155 | /* These are wrong, but it's better than nothing */ | ||
1156 | key = (SDLKey)(xsym & 0xFF); | ||
1157 | break; | ||
1158 | case 0xFE: | ||
1159 | key = ODD_keymap[xsym&0xFF]; | ||
1160 | break; | ||
1161 | case 0xFF: | ||
1162 | key = MISC_keymap[xsym&0xFF]; | ||
1163 | break; | ||
1164 | default: | ||
1165 | /* | ||
1166 | fprintf(stderr, "X11: Unhandled xsym, sym = 0x%04x\n", | ||
1167 | (unsigned int)xsym); | ||
1168 | */ | ||
1169 | break; | ||
1170 | } | ||
1171 | } else { | ||
1172 | /* X11 doesn't know how to translate the key! */ | ||
1173 | switch (kc) { | ||
1174 | /* Caution: | ||
1175 | These keycodes are from the Microsoft Keyboard | ||
1176 | */ | ||
1177 | case 115: | ||
1178 | key = SDLK_LSUPER; | ||
1179 | break; | ||
1180 | case 116: | ||
1181 | key = SDLK_RSUPER; | ||
1182 | break; | ||
1183 | case 117: | ||
1184 | key = SDLK_MENU; | ||
1185 | break; | ||
1186 | default: | ||
1187 | /* | ||
1188 | * no point in an error message; happens for | ||
1189 | * several keys when we get a keymap notify | ||
1190 | */ | ||
1191 | break; | ||
1192 | } | ||
1193 | } | ||
1194 | return key; | ||
1195 | } | ||
1196 | |||
1197 | /* X11 modifier masks for various keys */ | ||
1198 | static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask; | ||
1199 | static unsigned num_mask, mode_switch_mask; | ||
1200 | |||
1201 | static void get_modifier_masks(Display *display) | ||
1202 | { | ||
1203 | static unsigned got_masks; | ||
1204 | int i, j; | ||
1205 | XModifierKeymap *xmods; | ||
1206 | unsigned n; | ||
1207 | |||
1208 | if(got_masks) | ||
1209 | return; | ||
1210 | |||
1211 | xmods = XGetModifierMapping(display); | ||
1212 | n = xmods->max_keypermod; | ||
1213 | for(i = 3; i < 8; i++) { | ||
1214 | for(j = 0; j < n; j++) { | ||
1215 | KeyCode kc = xmods->modifiermap[i * n + j]; | ||
1216 | KeySym ks = XKeycodeToKeysym(display, kc, 0); | ||
1217 | unsigned mask = 1 << i; | ||
1218 | switch(ks) { | ||
1219 | case XK_Num_Lock: | ||
1220 | num_mask = mask; break; | ||
1221 | case XK_Alt_L: | ||
1222 | alt_l_mask = mask; break; | ||
1223 | case XK_Alt_R: | ||
1224 | alt_r_mask = mask; break; | ||
1225 | case XK_Meta_L: | ||
1226 | meta_l_mask = mask; break; | ||
1227 | case XK_Meta_R: | ||
1228 | meta_r_mask = mask; break; | ||
1229 | case XK_Mode_switch: | ||
1230 | mode_switch_mask = mask; break; | ||
1231 | } | ||
1232 | } | ||
1233 | } | ||
1234 | XFreeModifiermap(xmods); | ||
1235 | got_masks = 1; | ||
1236 | } | ||
1237 | |||
1238 | |||
1239 | /* | ||
1240 | * This function is semi-official; it is not officially exported and should | ||
1241 | * not be considered part of the SDL API, but may be used by client code | ||
1242 | * that *really* needs it (including legacy code). | ||
1243 | * It is slow, though, and should be avoided if possible. | ||
1244 | * | ||
1245 | * Note that it isn't completely accurate either; in particular, multi-key | ||
1246 | * sequences (dead accents, compose key sequences) will not work since the | ||
1247 | * state has been irrevocably lost. | ||
1248 | */ | ||
1249 | Uint16 X11_KeyToUnicode(SDLKey keysym, SDLMod modifiers) | ||
1250 | { | ||
1251 | struct SDL_VideoDevice *this = current_video; | ||
1252 | char keybuf[32]; | ||
1253 | int i; | ||
1254 | KeySym xsym = 0; | ||
1255 | XKeyEvent xkey; | ||
1256 | Uint16 unicode; | ||
1257 | |||
1258 | if ( !this || !SDL_Display ) { | ||
1259 | return 0; | ||
1260 | } | ||
1261 | |||
1262 | SDL_memset(&xkey, 0, sizeof(xkey)); | ||
1263 | xkey.display = SDL_Display; | ||
1264 | |||
1265 | xsym = keysym; /* last resort if not found */ | ||
1266 | for (i = 0; i < 256; ++i) { | ||
1267 | if ( MISC_keymap[i] == keysym ) { | ||
1268 | xsym = 0xFF00 | i; | ||
1269 | break; | ||
1270 | } else if ( ODD_keymap[i] == keysym ) { | ||
1271 | xsym = 0xFE00 | i; | ||
1272 | break; | ||
1273 | } | ||
1274 | } | ||
1275 | |||
1276 | xkey.keycode = XKeysymToKeycode(xkey.display, xsym); | ||
1277 | |||
1278 | get_modifier_masks(SDL_Display); | ||
1279 | if(modifiers & KMOD_SHIFT) | ||
1280 | xkey.state |= ShiftMask; | ||
1281 | if(modifiers & KMOD_CAPS) | ||
1282 | xkey.state |= LockMask; | ||
1283 | if(modifiers & KMOD_CTRL) | ||
1284 | xkey.state |= ControlMask; | ||
1285 | if(modifiers & KMOD_MODE) | ||
1286 | xkey.state |= mode_switch_mask; | ||
1287 | if(modifiers & KMOD_LALT) | ||
1288 | xkey.state |= alt_l_mask; | ||
1289 | if(modifiers & KMOD_RALT) | ||
1290 | xkey.state |= alt_r_mask; | ||
1291 | if(modifiers & KMOD_LMETA) | ||
1292 | xkey.state |= meta_l_mask; | ||
1293 | if(modifiers & KMOD_RMETA) | ||
1294 | xkey.state |= meta_r_mask; | ||
1295 | if(modifiers & KMOD_NUM) | ||
1296 | xkey.state |= num_mask; | ||
1297 | |||
1298 | unicode = 0; | ||
1299 | if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, NULL) ) | ||
1300 | unicode = (unsigned char)keybuf[0]; | ||
1301 | return(unicode); | ||
1302 | } | ||
1303 | |||
1304 | |||
1305 | /* | ||
1306 | * Called when focus is regained, to read the keyboard state and generate | ||
1307 | * synthetic keypress/release events. | ||
1308 | * key_vec is a bit vector of keycodes (256 bits) | ||
1309 | */ | ||
1310 | void X11_SetKeyboardState(Display *display, const char *key_vec) | ||
1311 | { | ||
1312 | char keys_return[32]; | ||
1313 | int i; | ||
1314 | Uint8 *kstate = SDL_GetKeyState(NULL); | ||
1315 | SDLMod modstate; | ||
1316 | Window junk_window; | ||
1317 | int x, y; | ||
1318 | unsigned int mask; | ||
1319 | |||
1320 | /* The first time the window is mapped, we initialize key state */ | ||
1321 | if ( ! key_vec ) { | ||
1322 | XQueryKeymap(display, keys_return); | ||
1323 | key_vec = keys_return; | ||
1324 | } | ||
1325 | |||
1326 | /* Get the keyboard modifier state */ | ||
1327 | modstate = 0; | ||
1328 | get_modifier_masks(display); | ||
1329 | if ( XQueryPointer(display, DefaultRootWindow(display), | ||
1330 | &junk_window, &junk_window, &x, &y, &x, &y, &mask) ) { | ||
1331 | if ( mask & LockMask ) { | ||
1332 | modstate |= KMOD_CAPS; | ||
1333 | } | ||
1334 | if ( mask & mode_switch_mask ) { | ||
1335 | modstate |= KMOD_MODE; | ||
1336 | } | ||
1337 | if ( mask & num_mask ) { | ||
1338 | modstate |= KMOD_NUM; | ||
1339 | } | ||
1340 | } | ||
1341 | |||
1342 | /* Zero the new keyboard state and generate it */ | ||
1343 | SDL_memset(kstate, 0, SDLK_LAST); | ||
1344 | /* | ||
1345 | * An obvious optimisation is to check entire longwords at a time in | ||
1346 | * both loops, but we can't be sure the arrays are aligned so it's not | ||
1347 | * worth the extra complexity | ||
1348 | */ | ||
1349 | for ( i = 0; i < 32; i++ ) { | ||
1350 | int j; | ||
1351 | if ( !key_vec[i] ) | ||
1352 | continue; | ||
1353 | for ( j = 0; j < 8; j++ ) { | ||
1354 | if ( key_vec[i] & (1 << j) ) { | ||
1355 | SDLKey key; | ||
1356 | KeyCode kc = (i << 3 | j); | ||
1357 | key = X11_TranslateKeycode(display, kc); | ||
1358 | if ( key == SDLK_UNKNOWN ) { | ||
1359 | continue; | ||
1360 | } | ||
1361 | kstate[key] = SDL_PRESSED; | ||
1362 | switch (key) { | ||
1363 | case SDLK_LSHIFT: | ||
1364 | modstate |= KMOD_LSHIFT; | ||
1365 | break; | ||
1366 | case SDLK_RSHIFT: | ||
1367 | modstate |= KMOD_RSHIFT; | ||
1368 | break; | ||
1369 | case SDLK_LCTRL: | ||
1370 | modstate |= KMOD_LCTRL; | ||
1371 | break; | ||
1372 | case SDLK_RCTRL: | ||
1373 | modstate |= KMOD_RCTRL; | ||
1374 | break; | ||
1375 | case SDLK_LALT: | ||
1376 | modstate |= KMOD_LALT; | ||
1377 | break; | ||
1378 | case SDLK_RALT: | ||
1379 | modstate |= KMOD_RALT; | ||
1380 | break; | ||
1381 | case SDLK_LMETA: | ||
1382 | modstate |= KMOD_LMETA; | ||
1383 | break; | ||
1384 | case SDLK_RMETA: | ||
1385 | modstate |= KMOD_RMETA; | ||
1386 | break; | ||
1387 | default: | ||
1388 | break; | ||
1389 | } | ||
1390 | } | ||
1391 | } | ||
1392 | } | ||
1393 | |||
1394 | /* Hack - set toggle key state */ | ||
1395 | if ( modstate & KMOD_CAPS ) { | ||
1396 | kstate[SDLK_CAPSLOCK] = SDL_PRESSED; | ||
1397 | } else { | ||
1398 | kstate[SDLK_CAPSLOCK] = SDL_RELEASED; | ||
1399 | } | ||
1400 | if ( modstate & KMOD_NUM ) { | ||
1401 | kstate[SDLK_NUMLOCK] = SDL_PRESSED; | ||
1402 | } else { | ||
1403 | kstate[SDLK_NUMLOCK] = SDL_RELEASED; | ||
1404 | } | ||
1405 | |||
1406 | /* Set the final modifier state */ | ||
1407 | SDL_SetModState(modstate); | ||
1408 | } | ||
1409 | |||
1410 | void X11_InitOSKeymap(_THIS) | ||
1411 | { | ||
1412 | X11_InitKeymap(); | ||
1413 | } | ||
1414 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11events_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11events_c.h deleted file mode 100644 index fe26d9c263..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11events_c.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_x11video.h" | ||
25 | |||
26 | /* Functions to be exported */ | ||
27 | extern void X11_InitOSKeymap(_THIS); | ||
28 | extern void X11_PumpEvents(_THIS); | ||
29 | extern void X11_SetKeyboardState(Display *display, const char *key_vec); | ||
30 | |||
31 | /* Variables to be exported */ | ||
32 | extern int X11_PendingConfigureNotifyWidth; | ||
33 | extern int X11_PendingConfigureNotifyHeight; | ||
34 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11gamma.c b/apps/plugins/sdl/src/video/x11/SDL_x11gamma.c deleted file mode 100644 index c6afbda11c..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11gamma.c +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL.h" | ||
25 | #include "SDL_events.h" | ||
26 | #include "../../events/SDL_events_c.h" | ||
27 | #include "SDL_x11video.h" | ||
28 | |||
29 | /* From the X server sources... */ | ||
30 | #define MAX_GAMMA 10.0 | ||
31 | #define MIN_GAMMA (1.0/MAX_GAMMA) | ||
32 | |||
33 | static int X11_SetGammaNoLock(_THIS, float red, float green, float blue) | ||
34 | { | ||
35 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
36 | if (use_vidmode >= 200) { | ||
37 | SDL_NAME(XF86VidModeGamma) gamma; | ||
38 | Bool succeeded; | ||
39 | |||
40 | /* Clamp the gamma values */ | ||
41 | if ( red < MIN_GAMMA ) { | ||
42 | gamma.red = MIN_GAMMA; | ||
43 | } else | ||
44 | if ( red > MAX_GAMMA ) { | ||
45 | gamma.red = MAX_GAMMA; | ||
46 | } else { | ||
47 | gamma.red = red; | ||
48 | } | ||
49 | if ( green < MIN_GAMMA ) { | ||
50 | gamma.green = MIN_GAMMA; | ||
51 | } else | ||
52 | if ( green > MAX_GAMMA ) { | ||
53 | gamma.green = MAX_GAMMA; | ||
54 | } else { | ||
55 | gamma.green = green; | ||
56 | } | ||
57 | if ( blue < MIN_GAMMA ) { | ||
58 | gamma.blue = MIN_GAMMA; | ||
59 | } else | ||
60 | if ( blue > MAX_GAMMA ) { | ||
61 | gamma.blue = MAX_GAMMA; | ||
62 | } else { | ||
63 | gamma.blue = blue; | ||
64 | } | ||
65 | if ( SDL_GetAppState() & SDL_APPACTIVE ) { | ||
66 | succeeded = SDL_NAME(XF86VidModeSetGamma)(SDL_Display, SDL_Screen, &gamma); | ||
67 | XSync(SDL_Display, False); | ||
68 | } else { | ||
69 | gamma_saved[0] = gamma.red; | ||
70 | gamma_saved[1] = gamma.green; | ||
71 | gamma_saved[2] = gamma.blue; | ||
72 | succeeded = True; | ||
73 | } | ||
74 | if ( succeeded ) { | ||
75 | ++gamma_changed; | ||
76 | } | ||
77 | return succeeded ? 0 : -1; | ||
78 | } | ||
79 | #endif | ||
80 | SDL_SetError("Gamma correction not supported"); | ||
81 | return -1; | ||
82 | } | ||
83 | int X11_SetVidModeGamma(_THIS, float red, float green, float blue) | ||
84 | { | ||
85 | int result; | ||
86 | |||
87 | SDL_Lock_EventThread(); | ||
88 | result = X11_SetGammaNoLock(this, red, green, blue); | ||
89 | SDL_Unlock_EventThread(); | ||
90 | |||
91 | return(result); | ||
92 | } | ||
93 | |||
94 | static int X11_GetGammaNoLock(_THIS, float *red, float *green, float *blue) | ||
95 | { | ||
96 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
97 | if (use_vidmode >= 200) { | ||
98 | SDL_NAME(XF86VidModeGamma) gamma; | ||
99 | if (SDL_NAME(XF86VidModeGetGamma)(SDL_Display, SDL_Screen, &gamma)) { | ||
100 | *red = gamma.red; | ||
101 | *green = gamma.green; | ||
102 | *blue = gamma.blue; | ||
103 | return 0; | ||
104 | } | ||
105 | return -1; | ||
106 | } | ||
107 | #endif | ||
108 | return -1; | ||
109 | } | ||
110 | int X11_GetVidModeGamma(_THIS, float *red, float *green, float *blue) | ||
111 | { | ||
112 | int result; | ||
113 | |||
114 | SDL_Lock_EventThread(); | ||
115 | result = X11_GetGammaNoLock(this, red, green, blue); | ||
116 | SDL_Unlock_EventThread(); | ||
117 | |||
118 | return(result); | ||
119 | } | ||
120 | |||
121 | void X11_SaveVidModeGamma(_THIS) | ||
122 | { | ||
123 | /* Try to save the current gamma, otherwise disable gamma control */ | ||
124 | if ( X11_GetGammaNoLock(this, | ||
125 | &gamma_saved[0], &gamma_saved[1], &gamma_saved[2]) < 0 ) { | ||
126 | this->SetGamma = 0; | ||
127 | this->GetGamma = 0; | ||
128 | } | ||
129 | gamma_changed = 0; | ||
130 | } | ||
131 | void X11_SwapVidModeGamma(_THIS) | ||
132 | { | ||
133 | float new_gamma[3]; | ||
134 | |||
135 | if ( gamma_changed ) { | ||
136 | new_gamma[0] = gamma_saved[0]; | ||
137 | new_gamma[1] = gamma_saved[1]; | ||
138 | new_gamma[2] = gamma_saved[2]; | ||
139 | X11_GetGammaNoLock(this, &gamma_saved[0], &gamma_saved[1], &gamma_saved[2]); | ||
140 | X11_SetGammaNoLock(this, new_gamma[0], new_gamma[1], new_gamma[2]); | ||
141 | } | ||
142 | } | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11gamma_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11gamma_c.h deleted file mode 100644 index c46350fd22..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11gamma_c.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_x11gamma_h | ||
25 | #define _SDL_x11gamma_h | ||
26 | |||
27 | extern int X11_SetVidModeGamma(_THIS, float red, float green, float blue); | ||
28 | extern int X11_GetVidModeGamma(_THIS, float *red, float *green, float *blue); | ||
29 | extern void X11_SaveVidModeGamma(_THIS); | ||
30 | extern void X11_SwapVidModeGamma(_THIS); | ||
31 | |||
32 | #endif | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11gl.c b/apps/plugins/sdl/src/video/x11/SDL_x11gl.c deleted file mode 100644 index aa5297b674..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11gl.c +++ /dev/null | |||
@@ -1,577 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_x11video.h" | ||
25 | #include "../../events/SDL_events_c.h" | ||
26 | #include "SDL_x11dga_c.h" | ||
27 | #include "SDL_x11gl_c.h" | ||
28 | |||
29 | #if defined(__IRIX__) | ||
30 | /* IRIX doesn't have a GL library versioning system */ | ||
31 | #define DEFAULT_OPENGL "libGL.so" | ||
32 | #elif defined(__MACOSX__) | ||
33 | #define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib" | ||
34 | #elif defined(__QNXNTO__) | ||
35 | #define DEFAULT_OPENGL "libGL.so.3" | ||
36 | #elif defined(__OpenBSD__) | ||
37 | #define DEFAULT_OPENGL "libGL.so.4.0" | ||
38 | #else | ||
39 | #define DEFAULT_OPENGL "libGL.so.1" | ||
40 | #endif | ||
41 | |||
42 | #ifndef GLX_ARB_multisample | ||
43 | #define GLX_ARB_multisample | ||
44 | #define GLX_SAMPLE_BUFFERS_ARB 100000 | ||
45 | #define GLX_SAMPLES_ARB 100001 | ||
46 | #endif | ||
47 | |||
48 | /* GLX_EXT_visual_rating stuff that might not be in the system headers... */ | ||
49 | #ifndef GLX_VISUAL_CAVEAT_EXT | ||
50 | #define GLX_VISUAL_CAVEAT_EXT 0x20 | ||
51 | #endif | ||
52 | #ifndef GLX_NONE_EXT | ||
53 | #define GLX_NONE_EXT 0x8000 | ||
54 | #endif | ||
55 | #ifndef GLX_SLOW_VISUAL_EXT | ||
56 | #define GLX_SLOW_VISUAL_EXT 0x8001 | ||
57 | #endif | ||
58 | #ifndef GLX_NON_CONFORMANT_VISUAL_EXT | ||
59 | #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D | ||
60 | #endif | ||
61 | |||
62 | |||
63 | #if SDL_VIDEO_OPENGL_GLX | ||
64 | static int glXExtensionSupported(_THIS, const char *extension) | ||
65 | { | ||
66 | const char *extensions; | ||
67 | const char *start; | ||
68 | const char *where, *terminator; | ||
69 | |||
70 | /* Extension names should not have spaces. */ | ||
71 | where = SDL_strchr(extension, ' '); | ||
72 | if ( where || *extension == '\0' ) { | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | extensions = this->gl_data->glXQueryExtensionsString(GFX_Display,SDL_Screen); | ||
77 | /* It takes a bit of care to be fool-proof about parsing the | ||
78 | * OpenGL extensions string. Don't be fooled by sub-strings, etc. | ||
79 | */ | ||
80 | |||
81 | /* http://bugs.debian.org/537487 */ | ||
82 | if (extensions == NULL) { | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | start = extensions; | ||
87 | |||
88 | for (;;) { | ||
89 | where = SDL_strstr(start, extension); | ||
90 | if (!where) break; | ||
91 | |||
92 | terminator = where + strlen(extension); | ||
93 | if (where == start || *(where - 1) == ' ') | ||
94 | if (*terminator == ' ' || *terminator == '\0') return 1; | ||
95 | |||
96 | start = terminator; | ||
97 | } | ||
98 | return 0; | ||
99 | } | ||
100 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
101 | |||
102 | XVisualInfo *X11_GL_GetVisual(_THIS) | ||
103 | { | ||
104 | #if SDL_VIDEO_OPENGL_GLX | ||
105 | /* 64 seems nice. */ | ||
106 | int attribs[64]; | ||
107 | int i; | ||
108 | |||
109 | /* load the gl driver from a default path */ | ||
110 | if ( ! this->gl_config.driver_loaded ) { | ||
111 | /* no driver has been loaded, use default (ourselves) */ | ||
112 | if ( X11_GL_LoadLibrary(this, NULL) < 0 ) { | ||
113 | return NULL; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /* See if we already have a window which we must use */ | ||
118 | if ( SDL_windowid ) { | ||
119 | XWindowAttributes a; | ||
120 | XVisualInfo vi_in; | ||
121 | int out_count; | ||
122 | |||
123 | XGetWindowAttributes(SDL_Display, SDL_Window, &a); | ||
124 | vi_in.screen = SDL_Screen; | ||
125 | vi_in.visualid = XVisualIDFromVisual(a.visual); | ||
126 | glx_visualinfo = XGetVisualInfo(SDL_Display, | ||
127 | VisualScreenMask|VisualIDMask, &vi_in, &out_count); | ||
128 | return glx_visualinfo; | ||
129 | } | ||
130 | |||
131 | /* Setup our GLX attributes according to the gl_config. */ | ||
132 | i = 0; | ||
133 | attribs[i++] = GLX_RGBA; | ||
134 | attribs[i++] = GLX_RED_SIZE; | ||
135 | attribs[i++] = this->gl_config.red_size; | ||
136 | attribs[i++] = GLX_GREEN_SIZE; | ||
137 | attribs[i++] = this->gl_config.green_size; | ||
138 | attribs[i++] = GLX_BLUE_SIZE; | ||
139 | attribs[i++] = this->gl_config.blue_size; | ||
140 | |||
141 | if( this->gl_config.alpha_size ) { | ||
142 | attribs[i++] = GLX_ALPHA_SIZE; | ||
143 | attribs[i++] = this->gl_config.alpha_size; | ||
144 | } | ||
145 | |||
146 | if( this->gl_config.double_buffer ) { | ||
147 | attribs[i++] = GLX_DOUBLEBUFFER; | ||
148 | } | ||
149 | |||
150 | attribs[i++] = GLX_DEPTH_SIZE; | ||
151 | attribs[i++] = this->gl_config.depth_size; | ||
152 | |||
153 | if( this->gl_config.stencil_size ) { | ||
154 | attribs[i++] = GLX_STENCIL_SIZE; | ||
155 | attribs[i++] = this->gl_config.stencil_size; | ||
156 | } | ||
157 | |||
158 | if( this->gl_config.accum_red_size ) { | ||
159 | attribs[i++] = GLX_ACCUM_RED_SIZE; | ||
160 | attribs[i++] = this->gl_config.accum_red_size; | ||
161 | } | ||
162 | |||
163 | if( this->gl_config.accum_green_size ) { | ||
164 | attribs[i++] = GLX_ACCUM_GREEN_SIZE; | ||
165 | attribs[i++] = this->gl_config.accum_green_size; | ||
166 | } | ||
167 | |||
168 | if( this->gl_config.accum_blue_size ) { | ||
169 | attribs[i++] = GLX_ACCUM_BLUE_SIZE; | ||
170 | attribs[i++] = this->gl_config.accum_blue_size; | ||
171 | } | ||
172 | |||
173 | if( this->gl_config.accum_alpha_size ) { | ||
174 | attribs[i++] = GLX_ACCUM_ALPHA_SIZE; | ||
175 | attribs[i++] = this->gl_config.accum_alpha_size; | ||
176 | } | ||
177 | |||
178 | if( this->gl_config.stereo ) { | ||
179 | attribs[i++] = GLX_STEREO; | ||
180 | } | ||
181 | |||
182 | if( this->gl_config.multisamplebuffers ) { | ||
183 | attribs[i++] = GLX_SAMPLE_BUFFERS_ARB; | ||
184 | attribs[i++] = this->gl_config.multisamplebuffers; | ||
185 | } | ||
186 | |||
187 | if( this->gl_config.multisamplesamples ) { | ||
188 | attribs[i++] = GLX_SAMPLES_ARB; | ||
189 | attribs[i++] = this->gl_config.multisamplesamples; | ||
190 | } | ||
191 | |||
192 | if( this->gl_config.accelerated >= 0 && | ||
193 | glXExtensionSupported(this, "GLX_EXT_visual_rating") ) { | ||
194 | attribs[i++] = GLX_VISUAL_CAVEAT_EXT; | ||
195 | attribs[i++] = GLX_NONE_EXT; | ||
196 | } | ||
197 | |||
198 | #ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */ | ||
199 | if ( !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { | ||
200 | attribs[i++] = GLX_X_VISUAL_TYPE; | ||
201 | attribs[i++] = GLX_DIRECT_COLOR; | ||
202 | } | ||
203 | #endif | ||
204 | attribs[i++] = None; | ||
205 | |||
206 | glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display, | ||
207 | SDL_Screen, attribs); | ||
208 | #ifdef GLX_DIRECT_COLOR | ||
209 | if( !glx_visualinfo && !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { /* No DirectColor visual? Try again.. */ | ||
210 | attribs[i-3] = None; | ||
211 | glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display, | ||
212 | SDL_Screen, attribs); | ||
213 | } | ||
214 | #endif | ||
215 | if( !glx_visualinfo ) { | ||
216 | SDL_SetError( "Couldn't find matching GLX visual"); | ||
217 | return NULL; | ||
218 | } | ||
219 | /* | ||
220 | printf("Found GLX visual 0x%x\n", glx_visualinfo->visualid); | ||
221 | */ | ||
222 | return glx_visualinfo; | ||
223 | #else | ||
224 | SDL_SetError("X11 driver not configured with OpenGL"); | ||
225 | return NULL; | ||
226 | #endif | ||
227 | } | ||
228 | |||
229 | int X11_GL_CreateWindow(_THIS, int w, int h) | ||
230 | { | ||
231 | int retval; | ||
232 | #if SDL_VIDEO_OPENGL_GLX | ||
233 | XSetWindowAttributes attributes; | ||
234 | unsigned long mask; | ||
235 | unsigned long black; | ||
236 | |||
237 | black = (glx_visualinfo->visual == DefaultVisual(SDL_Display, | ||
238 | SDL_Screen)) | ||
239 | ? BlackPixel(SDL_Display, SDL_Screen) : 0; | ||
240 | attributes.background_pixel = black; | ||
241 | attributes.border_pixel = black; | ||
242 | attributes.colormap = SDL_XColorMap; | ||
243 | mask = CWBackPixel | CWBorderPixel | CWColormap; | ||
244 | |||
245 | SDL_Window = XCreateWindow(SDL_Display, WMwindow, | ||
246 | 0, 0, w, h, 0, glx_visualinfo->depth, | ||
247 | InputOutput, glx_visualinfo->visual, | ||
248 | mask, &attributes); | ||
249 | if ( !SDL_Window ) { | ||
250 | SDL_SetError("Could not create window"); | ||
251 | return -1; | ||
252 | } | ||
253 | retval = 0; | ||
254 | #else | ||
255 | SDL_SetError("X11 driver not configured with OpenGL"); | ||
256 | retval = -1; | ||
257 | #endif | ||
258 | return(retval); | ||
259 | } | ||
260 | |||
261 | int X11_GL_CreateContext(_THIS) | ||
262 | { | ||
263 | int retval; | ||
264 | #if SDL_VIDEO_OPENGL_GLX | ||
265 | |||
266 | /* We do this to create a clean separation between X and GLX errors. */ | ||
267 | XSync( SDL_Display, False ); | ||
268 | glx_context = this->gl_data->glXCreateContext(GFX_Display, | ||
269 | glx_visualinfo, NULL, True); | ||
270 | XSync( GFX_Display, False ); | ||
271 | |||
272 | if ( glx_context == NULL ) { | ||
273 | SDL_SetError("Could not create GL context"); | ||
274 | return(-1); | ||
275 | } | ||
276 | if ( X11_GL_MakeCurrent(this) < 0 ) { | ||
277 | return(-1); | ||
278 | } | ||
279 | gl_active = 1; | ||
280 | |||
281 | if ( !glXExtensionSupported(this, "GLX_SGI_swap_control") ) { | ||
282 | this->gl_data->glXSwapIntervalSGI = NULL; | ||
283 | } | ||
284 | if ( !glXExtensionSupported(this, "GLX_MESA_swap_control") ) { | ||
285 | this->gl_data->glXSwapIntervalMESA = NULL; | ||
286 | } | ||
287 | if ( !glXExtensionSupported(this, "GLX_EXT_swap_control") ) { | ||
288 | this->gl_data->glXSwapIntervalEXT = NULL; | ||
289 | } | ||
290 | |||
291 | if ( this->gl_config.swap_control >= 0 ) { | ||
292 | int rc = -1; | ||
293 | if ( this->gl_data->glXSwapIntervalEXT ) { | ||
294 | rc = this->gl_data->glXSwapIntervalEXT(GFX_Display, SDL_Window, | ||
295 | this->gl_config.swap_control); | ||
296 | } else if ( this->gl_data->glXSwapIntervalMESA ) { | ||
297 | rc = this->gl_data->glXSwapIntervalMESA(this->gl_config.swap_control); | ||
298 | } else if ( this->gl_data->glXSwapIntervalSGI ) { | ||
299 | rc = this->gl_data->glXSwapIntervalSGI(this->gl_config.swap_control); | ||
300 | } | ||
301 | if (rc == 0) { | ||
302 | this->gl_data->swap_interval = this->gl_config.swap_control; | ||
303 | } | ||
304 | } | ||
305 | #else | ||
306 | SDL_SetError("X11 driver not configured with OpenGL"); | ||
307 | #endif | ||
308 | if ( gl_active ) { | ||
309 | retval = 0; | ||
310 | } else { | ||
311 | retval = -1; | ||
312 | } | ||
313 | return(retval); | ||
314 | } | ||
315 | |||
316 | void X11_GL_Shutdown(_THIS) | ||
317 | { | ||
318 | #if SDL_VIDEO_OPENGL_GLX | ||
319 | /* Clean up OpenGL */ | ||
320 | if( glx_context ) { | ||
321 | this->gl_data->glXMakeCurrent(GFX_Display, None, NULL); | ||
322 | |||
323 | if (glx_context != NULL) | ||
324 | this->gl_data->glXDestroyContext(GFX_Display, glx_context); | ||
325 | |||
326 | glx_context = NULL; | ||
327 | } | ||
328 | gl_active = 0; | ||
329 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
330 | } | ||
331 | |||
332 | #if SDL_VIDEO_OPENGL_GLX | ||
333 | |||
334 | /* Make the current context active */ | ||
335 | int X11_GL_MakeCurrent(_THIS) | ||
336 | { | ||
337 | int retval; | ||
338 | |||
339 | retval = 0; | ||
340 | if ( ! this->gl_data->glXMakeCurrent(GFX_Display, | ||
341 | SDL_Window, glx_context) ) { | ||
342 | SDL_SetError("Unable to make GL context current"); | ||
343 | retval = -1; | ||
344 | } | ||
345 | XSync( GFX_Display, False ); | ||
346 | |||
347 | /* More Voodoo X server workarounds... Grr... */ | ||
348 | SDL_Lock_EventThread(); | ||
349 | X11_CheckDGAMouse(this); | ||
350 | SDL_Unlock_EventThread(); | ||
351 | |||
352 | return(retval); | ||
353 | } | ||
354 | |||
355 | /* Get attribute data from glX. */ | ||
356 | int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) | ||
357 | { | ||
358 | int retval = -1; | ||
359 | int unsupported = 0; | ||
360 | int glx_attrib = None; | ||
361 | |||
362 | switch( attrib ) { | ||
363 | case SDL_GL_RED_SIZE: | ||
364 | glx_attrib = GLX_RED_SIZE; | ||
365 | break; | ||
366 | case SDL_GL_GREEN_SIZE: | ||
367 | glx_attrib = GLX_GREEN_SIZE; | ||
368 | break; | ||
369 | case SDL_GL_BLUE_SIZE: | ||
370 | glx_attrib = GLX_BLUE_SIZE; | ||
371 | break; | ||
372 | case SDL_GL_ALPHA_SIZE: | ||
373 | glx_attrib = GLX_ALPHA_SIZE; | ||
374 | break; | ||
375 | case SDL_GL_DOUBLEBUFFER: | ||
376 | glx_attrib = GLX_DOUBLEBUFFER; | ||
377 | break; | ||
378 | case SDL_GL_BUFFER_SIZE: | ||
379 | glx_attrib = GLX_BUFFER_SIZE; | ||
380 | break; | ||
381 | case SDL_GL_DEPTH_SIZE: | ||
382 | glx_attrib = GLX_DEPTH_SIZE; | ||
383 | break; | ||
384 | case SDL_GL_STENCIL_SIZE: | ||
385 | glx_attrib = GLX_STENCIL_SIZE; | ||
386 | break; | ||
387 | case SDL_GL_ACCUM_RED_SIZE: | ||
388 | glx_attrib = GLX_ACCUM_RED_SIZE; | ||
389 | break; | ||
390 | case SDL_GL_ACCUM_GREEN_SIZE: | ||
391 | glx_attrib = GLX_ACCUM_GREEN_SIZE; | ||
392 | break; | ||
393 | case SDL_GL_ACCUM_BLUE_SIZE: | ||
394 | glx_attrib = GLX_ACCUM_BLUE_SIZE; | ||
395 | break; | ||
396 | case SDL_GL_ACCUM_ALPHA_SIZE: | ||
397 | glx_attrib = GLX_ACCUM_ALPHA_SIZE; | ||
398 | break; | ||
399 | case SDL_GL_STEREO: | ||
400 | glx_attrib = GLX_STEREO; | ||
401 | break; | ||
402 | case SDL_GL_MULTISAMPLEBUFFERS: | ||
403 | glx_attrib = GLX_SAMPLE_BUFFERS_ARB; | ||
404 | break; | ||
405 | case SDL_GL_MULTISAMPLESAMPLES: | ||
406 | glx_attrib = GLX_SAMPLES_ARB; | ||
407 | break; | ||
408 | case SDL_GL_ACCELERATED_VISUAL: | ||
409 | if ( glXExtensionSupported(this, "GLX_EXT_visual_rating") ) { | ||
410 | glx_attrib = GLX_VISUAL_CAVEAT_EXT; | ||
411 | retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value); | ||
412 | if ( *value == GLX_SLOW_VISUAL_EXT ) { | ||
413 | *value = SDL_FALSE; | ||
414 | } else { | ||
415 | *value = SDL_TRUE; | ||
416 | } | ||
417 | return retval; | ||
418 | } else { | ||
419 | unsupported = 1; | ||
420 | } | ||
421 | break; | ||
422 | case SDL_GL_SWAP_CONTROL: | ||
423 | if ( ( this->gl_data->glXSwapIntervalEXT ) || | ||
424 | ( this->gl_data->glXSwapIntervalMESA ) || | ||
425 | ( this->gl_data->glXSwapIntervalSGI ) ) { | ||
426 | *value = this->gl_data->swap_interval; | ||
427 | return 0; | ||
428 | } else { | ||
429 | unsupported = 1; | ||
430 | } | ||
431 | break; | ||
432 | default: | ||
433 | unsupported = 1; | ||
434 | break; | ||
435 | } | ||
436 | |||
437 | if (unsupported) { | ||
438 | SDL_SetError("OpenGL attribute is unsupported on this system"); | ||
439 | } else { | ||
440 | retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value); | ||
441 | } | ||
442 | return retval; | ||
443 | } | ||
444 | |||
445 | void X11_GL_SwapBuffers(_THIS) | ||
446 | { | ||
447 | this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window); | ||
448 | } | ||
449 | |||
450 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
451 | |||
452 | #define OPENGL_REQUIRS_DLOPEN | ||
453 | #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) | ||
454 | #include <dlfcn.h> | ||
455 | #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) | ||
456 | #define GL_LoadFunction dlsym | ||
457 | #define GL_UnloadObject dlclose | ||
458 | #else | ||
459 | #define GL_LoadObject SDL_LoadObject | ||
460 | #define GL_LoadFunction SDL_LoadFunction | ||
461 | #define GL_UnloadObject SDL_UnloadObject | ||
462 | #endif | ||
463 | |||
464 | void X11_GL_UnloadLibrary(_THIS) | ||
465 | { | ||
466 | #if SDL_VIDEO_OPENGL_GLX | ||
467 | if ( this->gl_config.driver_loaded ) { | ||
468 | |||
469 | GL_UnloadObject(this->gl_config.dll_handle); | ||
470 | |||
471 | this->gl_data->glXGetProcAddress = NULL; | ||
472 | this->gl_data->glXChooseVisual = NULL; | ||
473 | this->gl_data->glXCreateContext = NULL; | ||
474 | this->gl_data->glXDestroyContext = NULL; | ||
475 | this->gl_data->glXMakeCurrent = NULL; | ||
476 | this->gl_data->glXSwapBuffers = NULL; | ||
477 | this->gl_data->glXSwapIntervalSGI = NULL; | ||
478 | this->gl_data->glXSwapIntervalMESA = NULL; | ||
479 | this->gl_data->glXSwapIntervalEXT = NULL; | ||
480 | |||
481 | this->gl_config.dll_handle = NULL; | ||
482 | this->gl_config.driver_loaded = 0; | ||
483 | } | ||
484 | #endif | ||
485 | } | ||
486 | |||
487 | #if SDL_VIDEO_OPENGL_GLX | ||
488 | |||
489 | /* Passing a NULL path means load pointers from the application */ | ||
490 | int X11_GL_LoadLibrary(_THIS, const char* path) | ||
491 | { | ||
492 | void* handle = NULL; | ||
493 | |||
494 | if ( gl_active ) { | ||
495 | SDL_SetError("OpenGL context already created"); | ||
496 | return -1; | ||
497 | } | ||
498 | |||
499 | if ( path == NULL ) { | ||
500 | path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); | ||
501 | if ( path == NULL ) { | ||
502 | path = DEFAULT_OPENGL; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | handle = GL_LoadObject(path); | ||
507 | if ( handle == NULL ) { | ||
508 | #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) | ||
509 | SDL_SetError("Failed loading %s", path); | ||
510 | #else | ||
511 | /* SDL_LoadObject() will call SDL_SetError() for us. */ | ||
512 | #endif | ||
513 | return -1; | ||
514 | } | ||
515 | |||
516 | /* Unload the old driver and reset the pointers */ | ||
517 | X11_GL_UnloadLibrary(this); | ||
518 | |||
519 | /* Save the handle for X11_GL_GetProcAddress() */ | ||
520 | this->gl_config.dll_handle = handle; | ||
521 | |||
522 | /* Load new function pointers */ | ||
523 | this->gl_data->glXGetProcAddress = | ||
524 | (void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB"); | ||
525 | this->gl_data->glXChooseVisual = | ||
526 | (XVisualInfo *(*)(Display *, int, int *)) X11_GL_GetProcAddress(this, "glXChooseVisual"); | ||
527 | this->gl_data->glXCreateContext = | ||
528 | (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) X11_GL_GetProcAddress(this, "glXCreateContext"); | ||
529 | this->gl_data->glXDestroyContext = | ||
530 | (void (*)(Display *, GLXContext)) X11_GL_GetProcAddress(this, "glXDestroyContext"); | ||
531 | this->gl_data->glXMakeCurrent = | ||
532 | (int (*)(Display *, GLXDrawable, GLXContext)) X11_GL_GetProcAddress(this, "glXMakeCurrent"); | ||
533 | this->gl_data->glXSwapBuffers = | ||
534 | (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(this, "glXSwapBuffers"); | ||
535 | this->gl_data->glXGetConfig = | ||
536 | (int (*)(Display *, XVisualInfo *, int, int *)) X11_GL_GetProcAddress(this, "glXGetConfig"); | ||
537 | this->gl_data->glXQueryExtensionsString = | ||
538 | (const char *(*)(Display *, int)) X11_GL_GetProcAddress(this, "glXQueryExtensionsString"); | ||
539 | this->gl_data->glXSwapIntervalSGI = | ||
540 | (int (*)(int)) X11_GL_GetProcAddress(this, "glXSwapIntervalSGI"); | ||
541 | this->gl_data->glXSwapIntervalMESA = | ||
542 | (GLint (*)(unsigned)) X11_GL_GetProcAddress(this, "glXSwapIntervalMESA"); | ||
543 | this->gl_data->glXSwapIntervalEXT = | ||
544 | (int (*)(Display*,GLXDrawable,int)) X11_GL_GetProcAddress(this, "glXSwapIntervalEXT"); | ||
545 | |||
546 | if ( (this->gl_data->glXChooseVisual == NULL) || | ||
547 | (this->gl_data->glXCreateContext == NULL) || | ||
548 | (this->gl_data->glXDestroyContext == NULL) || | ||
549 | (this->gl_data->glXMakeCurrent == NULL) || | ||
550 | (this->gl_data->glXSwapBuffers == NULL) || | ||
551 | (this->gl_data->glXGetConfig == NULL) || | ||
552 | (this->gl_data->glXQueryExtensionsString == NULL)) { | ||
553 | GL_UnloadObject(this->gl_config.dll_handle); | ||
554 | this->gl_config.dll_handle = NULL; | ||
555 | SDL_SetError("Could not retrieve OpenGL functions"); | ||
556 | return -1; | ||
557 | } | ||
558 | |||
559 | this->gl_config.driver_loaded = 1; | ||
560 | if ( path ) { | ||
561 | SDL_strlcpy(this->gl_config.driver_path, path, | ||
562 | SDL_arraysize(this->gl_config.driver_path)); | ||
563 | } else { | ||
564 | *this->gl_config.driver_path = '\0'; | ||
565 | } | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | void *X11_GL_GetProcAddress(_THIS, const char* proc) | ||
570 | { | ||
571 | if ( this->gl_data->glXGetProcAddress ) { | ||
572 | return this->gl_data->glXGetProcAddress((const GLubyte *)proc); | ||
573 | } | ||
574 | return GL_LoadFunction(this->gl_config.dll_handle, proc); | ||
575 | } | ||
576 | |||
577 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11gl_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11gl_c.h deleted file mode 100644 index b4822cb3c0..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11gl_c.h +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #if SDL_VIDEO_OPENGL_GLX | ||
25 | #include <GL/glx.h> | ||
26 | #include "SDL_loadso.h" | ||
27 | #endif | ||
28 | |||
29 | #include "../SDL_sysvideo.h" | ||
30 | |||
31 | struct SDL_PrivateGLData { | ||
32 | int gl_active; /* to stop switching drivers while we have a valid context */ | ||
33 | |||
34 | #if SDL_VIDEO_OPENGL_GLX | ||
35 | GLXContext glx_context; /* Current GL context */ | ||
36 | XVisualInfo* glx_visualinfo; /* XVisualInfo* returned by glXChooseVisual */ | ||
37 | |||
38 | void * (*glXGetProcAddress)(const GLubyte *procName); | ||
39 | |||
40 | XVisualInfo* (*glXChooseVisual) | ||
41 | ( Display* dpy, | ||
42 | int screen, | ||
43 | int* attribList ); | ||
44 | |||
45 | GLXContext (*glXCreateContext) | ||
46 | ( Display* dpy, | ||
47 | XVisualInfo* vis, | ||
48 | GLXContext shareList, | ||
49 | Bool direct ); | ||
50 | |||
51 | void (*glXDestroyContext) | ||
52 | ( Display* dpy, | ||
53 | GLXContext ctx ); | ||
54 | |||
55 | Bool (*glXMakeCurrent) | ||
56 | ( Display* dpy, | ||
57 | GLXDrawable drawable, | ||
58 | GLXContext ctx ); | ||
59 | |||
60 | void (*glXSwapBuffers) | ||
61 | ( Display* dpy, | ||
62 | GLXDrawable drawable ); | ||
63 | |||
64 | int (*glXGetConfig) | ||
65 | ( Display* dpy, | ||
66 | XVisualInfo* visual_info, | ||
67 | int attrib, | ||
68 | int* value ); | ||
69 | |||
70 | const char *(*glXQueryExtensionsString) | ||
71 | ( Display* dpy, | ||
72 | int screen ); | ||
73 | |||
74 | int (*glXSwapIntervalSGI) ( int interval ); | ||
75 | GLint (*glXSwapIntervalMESA) ( unsigned interval ); | ||
76 | int (*glXSwapIntervalEXT)( Display *dpy, GLXDrawable drw, int interval); | ||
77 | int swap_interval; | ||
78 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
79 | }; | ||
80 | |||
81 | /* Old variable names */ | ||
82 | #define gl_active (this->gl_data->gl_active) | ||
83 | #define glx_context (this->gl_data->glx_context) | ||
84 | #define glx_visualinfo (this->gl_data->glx_visualinfo) | ||
85 | |||
86 | /* OpenGL functions */ | ||
87 | extern XVisualInfo *X11_GL_GetVisual(_THIS); | ||
88 | extern int X11_GL_CreateWindow(_THIS, int w, int h); | ||
89 | extern int X11_GL_CreateContext(_THIS); | ||
90 | extern void X11_GL_Shutdown(_THIS); | ||
91 | #if SDL_VIDEO_OPENGL_GLX | ||
92 | extern int X11_GL_MakeCurrent(_THIS); | ||
93 | extern int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); | ||
94 | extern void X11_GL_SwapBuffers(_THIS); | ||
95 | extern int X11_GL_LoadLibrary(_THIS, const char* path); | ||
96 | extern void *X11_GL_GetProcAddress(_THIS, const char* proc); | ||
97 | #endif | ||
98 | extern void X11_GL_UnloadLibrary(_THIS); | ||
99 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11image.c b/apps/plugins/sdl/src/video/x11/SDL_x11image.c deleted file mode 100644 index 464bc37ba7..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11image.c +++ /dev/null | |||
@@ -1,316 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <unistd.h> | ||
26 | |||
27 | #include "SDL_endian.h" | ||
28 | #include "../../events/SDL_events_c.h" | ||
29 | #include "SDL_x11image_c.h" | ||
30 | |||
31 | #ifndef NO_SHARED_MEMORY | ||
32 | |||
33 | /* Shared memory error handler routine */ | ||
34 | static int shm_error; | ||
35 | static int (*X_handler)(Display *, XErrorEvent *) = NULL; | ||
36 | static int shm_errhandler(Display *d, XErrorEvent *e) | ||
37 | { | ||
38 | if ( e->error_code == BadAccess ) { | ||
39 | shm_error = True; | ||
40 | return(0); | ||
41 | } else | ||
42 | return(X_handler(d,e)); | ||
43 | } | ||
44 | |||
45 | static void try_mitshm(_THIS, SDL_Surface *screen) | ||
46 | { | ||
47 | /* Dynamic X11 may not have SHM entry points on this box. */ | ||
48 | if ((use_mitshm) && (!SDL_X11_HAVE_SHM)) | ||
49 | use_mitshm = 0; | ||
50 | |||
51 | if(!use_mitshm) | ||
52 | return; | ||
53 | shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, | ||
54 | IPC_CREAT | 0777); | ||
55 | if ( shminfo.shmid >= 0 ) { | ||
56 | shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); | ||
57 | shminfo.readOnly = False; | ||
58 | if ( shminfo.shmaddr != (char *)-1 ) { | ||
59 | shm_error = False; | ||
60 | X_handler = XSetErrorHandler(shm_errhandler); | ||
61 | XShmAttach(SDL_Display, &shminfo); | ||
62 | XSync(SDL_Display, True); | ||
63 | XSetErrorHandler(X_handler); | ||
64 | if ( shm_error ) | ||
65 | shmdt(shminfo.shmaddr); | ||
66 | } else { | ||
67 | shm_error = True; | ||
68 | } | ||
69 | shmctl(shminfo.shmid, IPC_RMID, NULL); | ||
70 | } else { | ||
71 | shm_error = True; | ||
72 | } | ||
73 | if ( shm_error ) | ||
74 | use_mitshm = 0; | ||
75 | if ( use_mitshm ) | ||
76 | screen->pixels = shminfo.shmaddr; | ||
77 | } | ||
78 | #endif /* ! NO_SHARED_MEMORY */ | ||
79 | |||
80 | /* Various screen update functions available */ | ||
81 | static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); | ||
82 | static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); | ||
83 | |||
84 | int X11_SetupImage(_THIS, SDL_Surface *screen) | ||
85 | { | ||
86 | #ifndef NO_SHARED_MEMORY | ||
87 | try_mitshm(this, screen); | ||
88 | if(use_mitshm) { | ||
89 | SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, | ||
90 | this->hidden->depth, ZPixmap, | ||
91 | shminfo.shmaddr, &shminfo, | ||
92 | screen->w, screen->h); | ||
93 | if(!SDL_Ximage) { | ||
94 | XShmDetach(SDL_Display, &shminfo); | ||
95 | XSync(SDL_Display, False); | ||
96 | shmdt(shminfo.shmaddr); | ||
97 | screen->pixels = NULL; | ||
98 | goto error; | ||
99 | } | ||
100 | this->UpdateRects = X11_MITSHMUpdate; | ||
101 | } | ||
102 | if(!use_mitshm) | ||
103 | #endif /* not NO_SHARED_MEMORY */ | ||
104 | { | ||
105 | screen->pixels = SDL_malloc(screen->h*screen->pitch); | ||
106 | if ( screen->pixels == NULL ) { | ||
107 | SDL_OutOfMemory(); | ||
108 | return -1; | ||
109 | } | ||
110 | SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, | ||
111 | this->hidden->depth, ZPixmap, 0, | ||
112 | (char *)screen->pixels, | ||
113 | screen->w, screen->h, | ||
114 | 32, 0); | ||
115 | if ( SDL_Ximage == NULL ) | ||
116 | goto error; | ||
117 | /* XPutImage will convert byte sex automatically */ | ||
118 | SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) | ||
119 | ? MSBFirst : LSBFirst; | ||
120 | this->UpdateRects = X11_NormalUpdate; | ||
121 | } | ||
122 | screen->pitch = SDL_Ximage->bytes_per_line; | ||
123 | return(0); | ||
124 | |||
125 | error: | ||
126 | SDL_SetError("Couldn't create XImage"); | ||
127 | return 1; | ||
128 | } | ||
129 | |||
130 | void X11_DestroyImage(_THIS, SDL_Surface *screen) | ||
131 | { | ||
132 | if ( SDL_Ximage ) { | ||
133 | XDestroyImage(SDL_Ximage); | ||
134 | #ifndef NO_SHARED_MEMORY | ||
135 | if ( use_mitshm ) { | ||
136 | XShmDetach(SDL_Display, &shminfo); | ||
137 | XSync(SDL_Display, False); | ||
138 | shmdt(shminfo.shmaddr); | ||
139 | } | ||
140 | #endif /* ! NO_SHARED_MEMORY */ | ||
141 | SDL_Ximage = NULL; | ||
142 | } | ||
143 | if ( screen ) { | ||
144 | screen->pixels = NULL; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /* Determine the number of CPUs in the system */ | ||
149 | static int num_CPU(void) | ||
150 | { | ||
151 | static int num_cpus = 0; | ||
152 | |||
153 | if(!num_cpus) { | ||
154 | #if defined(__LINUX__) | ||
155 | char line[BUFSIZ]; | ||
156 | FILE *pstat = fopen("/proc/stat", "r"); | ||
157 | if ( pstat ) { | ||
158 | while ( fgets(line, sizeof(line), pstat) ) { | ||
159 | if (SDL_memcmp(line, "cpu", 3) == 0 && line[3] != ' ') { | ||
160 | ++num_cpus; | ||
161 | } | ||
162 | } | ||
163 | fclose(pstat); | ||
164 | } | ||
165 | #elif defined(__IRIX__) | ||
166 | num_cpus = sysconf(_SC_NPROC_ONLN); | ||
167 | #elif defined(_SC_NPROCESSORS_ONLN) | ||
168 | /* number of processors online (SVR4.0MP compliant machines) */ | ||
169 | num_cpus = sysconf(_SC_NPROCESSORS_ONLN); | ||
170 | #elif defined(_SC_NPROCESSORS_CONF) | ||
171 | /* number of processors configured (SVR4.0MP compliant machines) */ | ||
172 | num_cpus = sysconf(_SC_NPROCESSORS_CONF); | ||
173 | #endif | ||
174 | if ( num_cpus <= 0 ) { | ||
175 | num_cpus = 1; | ||
176 | } | ||
177 | } | ||
178 | return num_cpus; | ||
179 | } | ||
180 | |||
181 | int X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) | ||
182 | { | ||
183 | int retval; | ||
184 | |||
185 | X11_DestroyImage(this, screen); | ||
186 | if ( flags & SDL_OPENGL ) { /* No image when using GL */ | ||
187 | retval = 0; | ||
188 | } else { | ||
189 | retval = X11_SetupImage(this, screen); | ||
190 | /* We support asynchronous blitting on the display */ | ||
191 | if ( flags & SDL_ASYNCBLIT ) { | ||
192 | /* This is actually slower on single-CPU systems, | ||
193 | probably because of CPU contention between the | ||
194 | X server and the application. | ||
195 | Note: Is this still true with XFree86 4.0? | ||
196 | */ | ||
197 | if ( num_CPU() > 1 ) { | ||
198 | screen->flags |= SDL_ASYNCBLIT; | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | return(retval); | ||
203 | } | ||
204 | |||
205 | /* We don't actually allow hardware surfaces other than the main one */ | ||
206 | int X11_AllocHWSurface(_THIS, SDL_Surface *surface) | ||
207 | { | ||
208 | return(-1); | ||
209 | } | ||
210 | void X11_FreeHWSurface(_THIS, SDL_Surface *surface) | ||
211 | { | ||
212 | return; | ||
213 | } | ||
214 | |||
215 | int X11_LockHWSurface(_THIS, SDL_Surface *surface) | ||
216 | { | ||
217 | if ( (surface == SDL_VideoSurface) && blit_queued ) { | ||
218 | XSync(GFX_Display, False); | ||
219 | blit_queued = 0; | ||
220 | } | ||
221 | return(0); | ||
222 | } | ||
223 | void X11_UnlockHWSurface(_THIS, SDL_Surface *surface) | ||
224 | { | ||
225 | return; | ||
226 | } | ||
227 | |||
228 | int X11_FlipHWSurface(_THIS, SDL_Surface *surface) | ||
229 | { | ||
230 | return(0); | ||
231 | } | ||
232 | |||
233 | static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) | ||
234 | { | ||
235 | int i; | ||
236 | |||
237 | for (i = 0; i < numrects; ++i) { | ||
238 | if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ | ||
239 | continue; | ||
240 | } | ||
241 | XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, | ||
242 | rects[i].x, rects[i].y, | ||
243 | rects[i].x, rects[i].y, rects[i].w, rects[i].h); | ||
244 | } | ||
245 | if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { | ||
246 | XFlush(GFX_Display); | ||
247 | blit_queued = 1; | ||
248 | } else { | ||
249 | XSync(GFX_Display, False); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects) | ||
254 | { | ||
255 | #ifndef NO_SHARED_MEMORY | ||
256 | int i; | ||
257 | |||
258 | for ( i=0; i<numrects; ++i ) { | ||
259 | if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ | ||
260 | continue; | ||
261 | } | ||
262 | XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, | ||
263 | rects[i].x, rects[i].y, | ||
264 | rects[i].x, rects[i].y, rects[i].w, rects[i].h, | ||
265 | False); | ||
266 | } | ||
267 | if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { | ||
268 | XFlush(GFX_Display); | ||
269 | blit_queued = 1; | ||
270 | } else { | ||
271 | XSync(GFX_Display, False); | ||
272 | } | ||
273 | #endif /* ! NO_SHARED_MEMORY */ | ||
274 | } | ||
275 | |||
276 | /* There's a problem with the automatic refreshing of the display. | ||
277 | Even though the XVideo code uses the GFX_Display to update the | ||
278 | video memory, it appears that updating the window asynchronously | ||
279 | from a different thread will cause "blackouts" of the window. | ||
280 | This is a sort of a hacked workaround for the problem. | ||
281 | */ | ||
282 | static int enable_autorefresh = 1; | ||
283 | |||
284 | void X11_DisableAutoRefresh(_THIS) | ||
285 | { | ||
286 | --enable_autorefresh; | ||
287 | } | ||
288 | |||
289 | void X11_EnableAutoRefresh(_THIS) | ||
290 | { | ||
291 | ++enable_autorefresh; | ||
292 | } | ||
293 | |||
294 | void X11_RefreshDisplay(_THIS) | ||
295 | { | ||
296 | /* Don't refresh a display that doesn't have an image (like GL) | ||
297 | Instead, post an expose event so the application can refresh. | ||
298 | */ | ||
299 | if ( ! SDL_Ximage || (enable_autorefresh <= 0) ) { | ||
300 | SDL_PrivateExpose(); | ||
301 | return; | ||
302 | } | ||
303 | #ifndef NO_SHARED_MEMORY | ||
304 | if ( this->UpdateRects == X11_MITSHMUpdate ) { | ||
305 | XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, | ||
306 | 0, 0, 0, 0, this->screen->w, this->screen->h, | ||
307 | False); | ||
308 | } else | ||
309 | #endif /* ! NO_SHARED_MEMORY */ | ||
310 | { | ||
311 | XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, | ||
312 | 0, 0, 0, 0, this->screen->w, this->screen->h); | ||
313 | } | ||
314 | XSync(SDL_Display, False); | ||
315 | } | ||
316 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11image_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11image_c.h deleted file mode 100644 index 2de15717ba..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11image_c.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_x11video.h" | ||
25 | |||
26 | extern int X11_SetupImage(_THIS, SDL_Surface *screen); | ||
27 | extern void X11_DestroyImage(_THIS, SDL_Surface *screen); | ||
28 | extern int X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags); | ||
29 | |||
30 | extern int X11_AllocHWSurface(_THIS, SDL_Surface *surface); | ||
31 | extern void X11_FreeHWSurface(_THIS, SDL_Surface *surface); | ||
32 | extern int X11_LockHWSurface(_THIS, SDL_Surface *surface); | ||
33 | extern void X11_UnlockHWSurface(_THIS, SDL_Surface *surface); | ||
34 | extern int X11_FlipHWSurface(_THIS, SDL_Surface *surface); | ||
35 | |||
36 | extern void X11_DisableAutoRefresh(_THIS); | ||
37 | extern void X11_EnableAutoRefresh(_THIS); | ||
38 | extern void X11_RefreshDisplay(_THIS); | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11modes.c b/apps/plugins/sdl/src/video/x11/SDL_x11modes.c deleted file mode 100644 index c232e6aa36..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11modes.c +++ /dev/null | |||
@@ -1,1143 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Utilities for getting and setting the X display mode */ | ||
25 | |||
26 | #include <stdio.h> | ||
27 | |||
28 | #include "SDL_timer.h" | ||
29 | #include "SDL_events.h" | ||
30 | #include "../../events/SDL_events_c.h" | ||
31 | #include "SDL_x11video.h" | ||
32 | #include "SDL_x11wm_c.h" | ||
33 | #include "SDL_x11modes_c.h" | ||
34 | #include "SDL_x11image_c.h" | ||
35 | |||
36 | /*#define X11MODES_DEBUG*/ | ||
37 | |||
38 | #define MAX(a, b) (a > b ? a : b) | ||
39 | |||
40 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
41 | static int cmpmodelist(const void *va, const void *vb) | ||
42 | { | ||
43 | const SDL_Rect *a = *(const SDL_Rect **)va; | ||
44 | const SDL_Rect *b = *(const SDL_Rect **)vb; | ||
45 | if ( a->w == b->w ) | ||
46 | return b->h - a->h; | ||
47 | else | ||
48 | return b->w - a->w; | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
53 | Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info) | ||
54 | { | ||
55 | Bool retval; | ||
56 | int dotclock; | ||
57 | SDL_NAME(XF86VidModeModeLine) l; | ||
58 | SDL_memset(&l, 0, sizeof(l)); | ||
59 | retval = SDL_NAME(XF86VidModeGetModeLine)(dpy, scr, &dotclock, &l); | ||
60 | info->dotclock = dotclock; | ||
61 | info->hdisplay = l.hdisplay; | ||
62 | info->hsyncstart = l.hsyncstart; | ||
63 | info->hsyncend = l.hsyncend; | ||
64 | info->htotal = l.htotal; | ||
65 | info->hskew = l.hskew; | ||
66 | info->vdisplay = l.vdisplay; | ||
67 | info->vsyncstart = l.vsyncstart; | ||
68 | info->vsyncend = l.vsyncend; | ||
69 | info->vtotal = l.vtotal; | ||
70 | info->flags = l.flags; | ||
71 | info->privsize = l.privsize; | ||
72 | info->private = l.private; | ||
73 | return retval; | ||
74 | } | ||
75 | #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | ||
76 | |||
77 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
78 | static void save_mode(_THIS) | ||
79 | { | ||
80 | SDL_memset(&saved_mode, 0, sizeof(saved_mode)); | ||
81 | SDL_NAME(XF86VidModeGetModeInfo)(SDL_Display,SDL_Screen,&saved_mode); | ||
82 | SDL_NAME(XF86VidModeGetViewPort)(SDL_Display,SDL_Screen,&saved_view.x,&saved_view.y); | ||
83 | } | ||
84 | #endif | ||
85 | |||
86 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
87 | static void restore_mode(_THIS) | ||
88 | { | ||
89 | SDL_NAME(XF86VidModeModeLine) mode; | ||
90 | int unused; | ||
91 | |||
92 | if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) { | ||
93 | if ( (saved_mode.hdisplay != mode.hdisplay) || | ||
94 | (saved_mode.vdisplay != mode.vdisplay) ) { | ||
95 | SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, &saved_mode); | ||
96 | } | ||
97 | } | ||
98 | if ( (saved_view.x != 0) || (saved_view.y != 0) ) { | ||
99 | SDL_NAME(XF86VidModeSetViewPort)(SDL_Display, SDL_Screen, saved_view.x, saved_view.y); | ||
100 | } | ||
101 | } | ||
102 | #endif | ||
103 | |||
104 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
105 | static int cmpmodes(const void *va, const void *vb) | ||
106 | { | ||
107 | const SDL_NAME(XF86VidModeModeInfo) *a = *(const SDL_NAME(XF86VidModeModeInfo)**)va; | ||
108 | const SDL_NAME(XF86VidModeModeInfo) *b = *(const SDL_NAME(XF86VidModeModeInfo)**)vb; | ||
109 | if ( a->hdisplay == b->hdisplay ) | ||
110 | return b->vdisplay - a->vdisplay; | ||
111 | else | ||
112 | return b->hdisplay - a->hdisplay; | ||
113 | } | ||
114 | #endif | ||
115 | |||
116 | static void get_real_resolution(_THIS, int* w, int* h); | ||
117 | |||
118 | static void set_best_resolution(_THIS, int width, int height) | ||
119 | { | ||
120 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
121 | if ( use_vidmode ) { | ||
122 | SDL_NAME(XF86VidModeModeLine) mode; | ||
123 | SDL_NAME(XF86VidModeModeInfo) **modes; | ||
124 | int i; | ||
125 | int nmodes; | ||
126 | int best = -1; | ||
127 | |||
128 | if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) && | ||
129 | SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) ) { | ||
130 | for ( i = 0; i < nmodes ; i++ ) { | ||
131 | if ( (modes[i]->hdisplay == width) && | ||
132 | (modes[i]->vdisplay == height) ) { | ||
133 | best = i; | ||
134 | break; | ||
135 | } | ||
136 | if ( modes[i]->hdisplay >= width && | ||
137 | modes[i]->vdisplay >= height ) { | ||
138 | if ( best < 0 || | ||
139 | (modes[i]->hdisplay < modes[best]->hdisplay && | ||
140 | modes[i]->vdisplay <= modes[best]->vdisplay) || | ||
141 | (modes[i]->vdisplay < modes[best]->vdisplay && | ||
142 | modes[i]->hdisplay <= modes[best]->hdisplay) ) { | ||
143 | best = i; | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | if ( best >= 0 && | ||
148 | ((modes[best]->hdisplay != mode.hdisplay) || | ||
149 | (modes[best]->vdisplay != mode.vdisplay)) ) { | ||
150 | #ifdef X11MODES_DEBUG | ||
151 | printf("Best Mode %d: %d x %d @ %d\n", best, | ||
152 | modes[best]->hdisplay, modes[best]->vdisplay, | ||
153 | (modes[best]->htotal && modes[best]->vtotal) ? (1000 * modes[best]->dotclock / (modes[best]->htotal * modes[best]->vtotal)) : 0 ); | ||
154 | #endif | ||
155 | SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[best]); | ||
156 | } | ||
157 | XFree(modes); | ||
158 | } | ||
159 | } | ||
160 | #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | ||
161 | |||
162 | /* XiG */ | ||
163 | #if SDL_VIDEO_DRIVER_X11_XME | ||
164 | if ( use_xme && SDL_modelist ) { | ||
165 | int i; | ||
166 | |||
167 | #ifdef X11MODES_DEBUG | ||
168 | fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n", | ||
169 | width, height); | ||
170 | #endif | ||
171 | for ( i=0; SDL_modelist[i]; ++i ) { | ||
172 | if ( (SDL_modelist[i]->w >= width) && | ||
173 | (SDL_modelist[i]->h >= height) ) { | ||
174 | break; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | if ( SDL_modelist[i] ) { /* found one, lets try it */ | ||
179 | int w, h; | ||
180 | |||
181 | /* check current mode so we can avoid uneccessary mode changes */ | ||
182 | get_real_resolution(this, &w, &h); | ||
183 | |||
184 | if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { | ||
185 | #ifdef X11MODES_DEBUG | ||
186 | fprintf(stderr, "XME: set_best_resolution: " | ||
187 | "XiGMiscChangeResolution: %d %d\n", | ||
188 | SDL_modelist[i]->w, SDL_modelist[i]->h); | ||
189 | #endif | ||
190 | XiGMiscChangeResolution(SDL_Display, | ||
191 | SDL_Screen, | ||
192 | 0, /* view */ | ||
193 | SDL_modelist[i]->w, | ||
194 | SDL_modelist[i]->h, | ||
195 | 0); | ||
196 | XSync(SDL_Display, False); | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | #endif /* SDL_VIDEO_DRIVER_X11_XME */ | ||
201 | |||
202 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
203 | if ( use_xrandr && SDL_modelist ) { | ||
204 | #ifdef X11MODES_DEBUG | ||
205 | fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n", | ||
206 | width, height); | ||
207 | #endif | ||
208 | int i, nsizes; | ||
209 | XRRScreenSize *sizes; | ||
210 | |||
211 | /* find the smallest resolution that is at least as big as the user requested */ | ||
212 | sizes = XRRConfigSizes(screen_config, &nsizes); | ||
213 | for ( i = (nsizes-1); i >= 0; i-- ) { | ||
214 | if ( (SDL_modelist[i]->w >= width) && | ||
215 | (SDL_modelist[i]->h >= height) ) { | ||
216 | break; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */ | ||
221 | int w, h; | ||
222 | |||
223 | /* check current mode so we can avoid uneccessary mode changes */ | ||
224 | get_real_resolution(this, &w, &h); | ||
225 | |||
226 | if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { | ||
227 | int size_id; | ||
228 | |||
229 | #ifdef X11MODES_DEBUG | ||
230 | fprintf(stderr, "XRANDR: set_best_resolution: " | ||
231 | "XXRSetScreenConfig: %d %d\n", | ||
232 | SDL_modelist[i]->w, SDL_modelist[i]->h); | ||
233 | #endif | ||
234 | |||
235 | /* find the matching size entry index */ | ||
236 | for ( size_id = 0; size_id < nsizes; ++size_id ) { | ||
237 | if ( (sizes[size_id].width == SDL_modelist[i]->w) && | ||
238 | (sizes[size_id].height == SDL_modelist[i]->h) ) | ||
239 | break; | ||
240 | } | ||
241 | |||
242 | XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root, | ||
243 | size_id, saved_rotation, CurrentTime); | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | ||
248 | } | ||
249 | |||
250 | static void get_real_resolution(_THIS, int* w, int* h) | ||
251 | { | ||
252 | #if SDL_VIDEO_DRIVER_X11_XME | ||
253 | if ( use_xme ) { | ||
254 | int ractive; | ||
255 | XiGMiscResolutionInfo *modelist; | ||
256 | |||
257 | XiGMiscQueryResolutions(SDL_Display, SDL_Screen, | ||
258 | 0, /* view */ | ||
259 | &ractive, &modelist); | ||
260 | *w = modelist[ractive].width; | ||
261 | *h = modelist[ractive].height; | ||
262 | #ifdef X11MODES_DEBUG | ||
263 | fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h); | ||
264 | #endif | ||
265 | XFree(modelist); | ||
266 | return; | ||
267 | } | ||
268 | #endif /* SDL_VIDEO_DRIVER_X11_XME */ | ||
269 | |||
270 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
271 | if ( use_vidmode ) { | ||
272 | SDL_NAME(XF86VidModeModeLine) mode; | ||
273 | int unused; | ||
274 | |||
275 | if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) { | ||
276 | *w = mode.hdisplay; | ||
277 | *h = mode.vdisplay; | ||
278 | return; | ||
279 | } | ||
280 | } | ||
281 | #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | ||
282 | |||
283 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
284 | if ( use_xrandr ) { | ||
285 | int nsizes; | ||
286 | XRRScreenSize* sizes; | ||
287 | |||
288 | sizes = XRRConfigSizes(screen_config, &nsizes); | ||
289 | if ( nsizes > 0 ) { | ||
290 | int cur_size; | ||
291 | Rotation cur_rotation; | ||
292 | |||
293 | cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation); | ||
294 | if ( cur_size >= 0 && cur_size < nsizes ) { | ||
295 | *w = sizes[cur_size].width; | ||
296 | *h = sizes[cur_size].height; | ||
297 | } | ||
298 | #ifdef X11MODES_DEBUG | ||
299 | fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h); | ||
300 | #endif | ||
301 | return; | ||
302 | } | ||
303 | } | ||
304 | #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | ||
305 | |||
306 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
307 | if ( use_xinerama ) { | ||
308 | *w = xinerama_info.width; | ||
309 | *h = xinerama_info.height; | ||
310 | return; | ||
311 | } | ||
312 | #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | ||
313 | |||
314 | *w = DisplayWidth(SDL_Display, SDL_Screen); | ||
315 | *h = DisplayHeight(SDL_Display, SDL_Screen); | ||
316 | } | ||
317 | |||
318 | /* Called after mapping a window - waits until the window is mapped */ | ||
319 | void X11_WaitMapped(_THIS, Window win) | ||
320 | { | ||
321 | XEvent event; | ||
322 | do { | ||
323 | XMaskEvent(SDL_Display, StructureNotifyMask, &event); | ||
324 | } while ( (event.type != MapNotify) || (event.xmap.event != win) ); | ||
325 | } | ||
326 | |||
327 | /* Called after unmapping a window - waits until the window is unmapped */ | ||
328 | void X11_WaitUnmapped(_THIS, Window win) | ||
329 | { | ||
330 | XEvent event; | ||
331 | do { | ||
332 | XMaskEvent(SDL_Display, StructureNotifyMask, &event); | ||
333 | } while ( (event.type != UnmapNotify) || (event.xunmap.event != win) ); | ||
334 | } | ||
335 | |||
336 | static void move_cursor_to(_THIS, int x, int y) | ||
337 | { | ||
338 | XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y); | ||
339 | } | ||
340 | |||
341 | static int add_default_visual(_THIS) | ||
342 | { | ||
343 | int i; | ||
344 | int n = this->hidden->nvisuals; | ||
345 | for (i=0; i<n; i++) { | ||
346 | if (this->hidden->visuals[i].visual == DefaultVisual(SDL_Display, SDL_Screen)) return n; | ||
347 | } | ||
348 | this->hidden->visuals[n].depth = DefaultDepth(SDL_Display, SDL_Screen);; | ||
349 | this->hidden->visuals[n].visual = DefaultVisual(SDL_Display, SDL_Screen);; | ||
350 | this->hidden->nvisuals++; | ||
351 | return(this->hidden->nvisuals); | ||
352 | } | ||
353 | static int add_visual(_THIS, int depth, int class) | ||
354 | { | ||
355 | XVisualInfo vi; | ||
356 | if(XMatchVisualInfo(SDL_Display, SDL_Screen, depth, class, &vi)) { | ||
357 | int n = this->hidden->nvisuals; | ||
358 | this->hidden->visuals[n].depth = vi.depth; | ||
359 | this->hidden->visuals[n].visual = vi.visual; | ||
360 | this->hidden->nvisuals++; | ||
361 | } | ||
362 | return(this->hidden->nvisuals); | ||
363 | } | ||
364 | static int add_visual_byid(_THIS, const char *visual_id) | ||
365 | { | ||
366 | XVisualInfo *vi, template; | ||
367 | int nvis; | ||
368 | |||
369 | if ( visual_id ) { | ||
370 | SDL_memset(&template, 0, (sizeof template)); | ||
371 | template.visualid = SDL_strtol(visual_id, NULL, 0); | ||
372 | vi = XGetVisualInfo(SDL_Display, VisualIDMask, &template, &nvis); | ||
373 | if ( vi ) { | ||
374 | int n = this->hidden->nvisuals; | ||
375 | this->hidden->visuals[n].depth = vi->depth; | ||
376 | this->hidden->visuals[n].visual = vi->visual; | ||
377 | this->hidden->nvisuals++; | ||
378 | XFree(vi); | ||
379 | } | ||
380 | } | ||
381 | return(this->hidden->nvisuals); | ||
382 | } | ||
383 | |||
384 | /* Global for the error handler */ | ||
385 | int vm_event, vm_error = -1; | ||
386 | |||
387 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
388 | static int CheckXinerama(_THIS, int *major, int *minor) | ||
389 | { | ||
390 | const char *env; | ||
391 | |||
392 | /* Default the extension not available */ | ||
393 | *major = *minor = 0; | ||
394 | |||
395 | /* Allow environment override */ | ||
396 | env = getenv("SDL_VIDEO_X11_XINERAMA"); | ||
397 | if ( env && !SDL_atoi(env) ) { | ||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | /* Query the extension version */ | ||
402 | if ( !SDL_NAME(XineramaQueryExtension)(SDL_Display, major, minor) || | ||
403 | !SDL_NAME(XineramaIsActive)(SDL_Display) ) { | ||
404 | return 0; | ||
405 | } | ||
406 | return 1; | ||
407 | } | ||
408 | #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | ||
409 | |||
410 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
411 | static int CheckXRandR(_THIS, int *major, int *minor) | ||
412 | { | ||
413 | const char *env; | ||
414 | |||
415 | /* Default the extension not available */ | ||
416 | *major = *minor = 0; | ||
417 | |||
418 | /* Allow environment override */ | ||
419 | env = getenv("SDL_VIDEO_X11_XRANDR"); | ||
420 | if ( env && !SDL_atoi(env) ) { | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | /* This defaults off now, due to KDE window maximize problems */ | ||
425 | if ( !env ) { | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | if ( !SDL_X11_HAVE_XRANDR ) { | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | /* Query the extension version */ | ||
434 | if ( !XRRQueryVersion(SDL_Display, major, minor) ) { | ||
435 | return 0; | ||
436 | } | ||
437 | return 1; | ||
438 | } | ||
439 | #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | ||
440 | |||
441 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
442 | static int CheckVidMode(_THIS, int *major, int *minor) | ||
443 | { | ||
444 | const char *env; | ||
445 | |||
446 | /* Default the extension not available */ | ||
447 | *major = *minor = 0; | ||
448 | |||
449 | /* Allow environment override */ | ||
450 | env = getenv("SDL_VIDEO_X11_VIDMODE"); | ||
451 | if ( env && !SDL_atoi(env) ) { | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | /* Metro-X 4.3.0 and earlier has a broken implementation of | ||
456 | XF86VidModeGetAllModeLines() - it hangs the client. | ||
457 | */ | ||
458 | if ( SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0 ) { | ||
459 | FILE *metro_fp; | ||
460 | |||
461 | metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r"); | ||
462 | if ( metro_fp != NULL ) { | ||
463 | int major, minor, patch, version, scannum; | ||
464 | major = 0; minor = 0; patch = 0; | ||
465 | scannum = fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch); | ||
466 | fclose(metro_fp); | ||
467 | if ( (scannum < 0) || (scannum > 3) ) { | ||
468 | return 0; /* we need _something_ useful from fscanf(). */ | ||
469 | } | ||
470 | version = major*100+minor*10+patch; | ||
471 | if ( version < 431 ) { | ||
472 | return 0; | ||
473 | } | ||
474 | } | ||
475 | } | ||
476 | |||
477 | /* Query the extension version */ | ||
478 | vm_error = -1; | ||
479 | if ( !SDL_NAME(XF86VidModeQueryExtension)(SDL_Display, &vm_event, &vm_error) || | ||
480 | !SDL_NAME(XF86VidModeQueryVersion)(SDL_Display, major, minor) ) { | ||
481 | return 0; | ||
482 | } | ||
483 | return 1; | ||
484 | } | ||
485 | #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | ||
486 | |||
487 | #if SDL_VIDEO_DRIVER_X11_XME | ||
488 | static int CheckXME(_THIS, int *major, int *minor) | ||
489 | { | ||
490 | const char *env; | ||
491 | |||
492 | /* Default the extension not available */ | ||
493 | *major = *minor = 0; | ||
494 | |||
495 | /* Allow environment override */ | ||
496 | env = getenv("SDL_VIDEO_X11_VIDMODE"); | ||
497 | if ( env && !SDL_atoi(env) ) { | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | /* Query the extension version */ | ||
502 | if ( !XiGMiscQueryVersion(SDL_Display, major, minor) ) { | ||
503 | return 0; | ||
504 | } | ||
505 | return 1; | ||
506 | } | ||
507 | #endif /* SDL_VIDEO_DRIVER_X11_XME */ | ||
508 | |||
509 | int X11_GetVideoModes(_THIS) | ||
510 | { | ||
511 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
512 | int xinerama_major, xinerama_minor; | ||
513 | #endif | ||
514 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
515 | int xrandr_major, xrandr_minor; | ||
516 | int nsizes; | ||
517 | XRRScreenSize *sizes; | ||
518 | #endif | ||
519 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
520 | int vm_major, vm_minor; | ||
521 | int nmodes; | ||
522 | SDL_NAME(XF86VidModeModeInfo) **modes; | ||
523 | #endif | ||
524 | #if SDL_VIDEO_DRIVER_X11_XME | ||
525 | int xme_major, xme_minor; | ||
526 | int ractive, nummodes; | ||
527 | XiGMiscResolutionInfo *modelist; | ||
528 | #endif | ||
529 | int i, n; | ||
530 | int screen_w; | ||
531 | int screen_h; | ||
532 | |||
533 | use_xinerama = 0; | ||
534 | use_xrandr = 0; | ||
535 | use_vidmode = 0; | ||
536 | use_xme = 0; | ||
537 | screen_w = DisplayWidth(SDL_Display, SDL_Screen); | ||
538 | screen_h = DisplayHeight(SDL_Display, SDL_Screen); | ||
539 | |||
540 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
541 | /* Query Xinerama extention */ | ||
542 | if ( CheckXinerama(this, &xinerama_major, &xinerama_minor) ) { | ||
543 | /* Find out which screen is the desired one */ | ||
544 | int desired = -1; | ||
545 | int screens; | ||
546 | int w, h; | ||
547 | SDL_NAME(XineramaScreenInfo) *xinerama; | ||
548 | |||
549 | const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY"); | ||
550 | if ( !variable ) { | ||
551 | variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD"); | ||
552 | } | ||
553 | if ( variable ) { | ||
554 | desired = SDL_atoi(variable); | ||
555 | } | ||
556 | #ifdef X11MODES_DEBUG | ||
557 | printf("X11 detected Xinerama:\n"); | ||
558 | #endif | ||
559 | xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens); | ||
560 | for ( i = 0; i < screens; i++ ) { | ||
561 | #ifdef X11MODES_DEBUG | ||
562 | printf("xinerama %d: %dx%d+%d+%d\n", | ||
563 | xinerama[i].screen_number, | ||
564 | xinerama[i].width, xinerama[i].height, | ||
565 | xinerama[i].x_org, xinerama[i].y_org); | ||
566 | #endif | ||
567 | if ( xinerama[i].screen_number == desired ) { | ||
568 | use_xinerama = 1; | ||
569 | xinerama_info = xinerama[i]; | ||
570 | } | ||
571 | } | ||
572 | XFree(xinerama); | ||
573 | |||
574 | if ( use_xinerama ) { | ||
575 | SDL_modelist = (SDL_Rect **)SDL_malloc(3*sizeof(SDL_Rect *)); | ||
576 | if ( !SDL_modelist ) { | ||
577 | SDL_OutOfMemory(); | ||
578 | return -1; | ||
579 | } | ||
580 | |||
581 | /* Add the full xinerama mode */ | ||
582 | n = 0; | ||
583 | w = xinerama_info.width; | ||
584 | h = xinerama_info.height; | ||
585 | if ( screen_w > w || screen_h > h) { | ||
586 | SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | ||
587 | if ( SDL_modelist[n] ) { | ||
588 | SDL_modelist[n]->x = 0; | ||
589 | SDL_modelist[n]->y = 0; | ||
590 | SDL_modelist[n]->w = screen_w; | ||
591 | SDL_modelist[n]->h = screen_h; | ||
592 | ++n; | ||
593 | } | ||
594 | } | ||
595 | |||
596 | /* Add the head xinerama mode */ | ||
597 | SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | ||
598 | if ( SDL_modelist[n] ) { | ||
599 | SDL_modelist[n]->x = 0; | ||
600 | SDL_modelist[n]->y = 0; | ||
601 | SDL_modelist[n]->w = w; | ||
602 | SDL_modelist[n]->h = h; | ||
603 | ++n; | ||
604 | } | ||
605 | SDL_modelist[n] = NULL; | ||
606 | } | ||
607 | } | ||
608 | #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | ||
609 | |||
610 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
611 | /* XRandR */ | ||
612 | /* require at least XRandR v1.0 (arbitrary) */ | ||
613 | if ( CheckXRandR(this, &xrandr_major, &xrandr_minor) && (xrandr_major >= 1) ) | ||
614 | { | ||
615 | #ifdef X11MODES_DEBUG | ||
616 | fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n", | ||
617 | xrandr_major, xrandr_minor); | ||
618 | #endif | ||
619 | |||
620 | /* save the screen configuration since we must reference it | ||
621 | each time we toggle modes. | ||
622 | */ | ||
623 | screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root); | ||
624 | |||
625 | /* retrieve the list of resolution */ | ||
626 | sizes = XRRConfigSizes(screen_config, &nsizes); | ||
627 | if (nsizes > 0) { | ||
628 | if ( SDL_modelist ) { | ||
629 | for ( i = 0; SDL_modelist[i]; ++i ) { | ||
630 | SDL_free(SDL_modelist[i]); | ||
631 | } | ||
632 | SDL_free(SDL_modelist); | ||
633 | } | ||
634 | SDL_modelist = (SDL_Rect **)malloc((nsizes+1)*sizeof(SDL_Rect *)); | ||
635 | if ( !SDL_modelist ) { | ||
636 | SDL_OutOfMemory(); | ||
637 | return -1; | ||
638 | } | ||
639 | for ( i=0; i < nsizes; i++ ) { | ||
640 | if ((SDL_modelist[i] = | ||
641 | (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL) | ||
642 | break; | ||
643 | #ifdef X11MODES_DEBUG | ||
644 | fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n", | ||
645 | i, sizes[i].width, sizes[i].height); | ||
646 | #endif | ||
647 | |||
648 | SDL_modelist[i]->x = 0; | ||
649 | SDL_modelist[i]->y = 0; | ||
650 | SDL_modelist[i]->w = sizes[i].width; | ||
651 | SDL_modelist[i]->h = sizes[i].height; | ||
652 | |||
653 | } | ||
654 | /* sort the mode list descending as SDL expects */ | ||
655 | SDL_qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist); | ||
656 | SDL_modelist[i] = NULL; /* terminator */ | ||
657 | |||
658 | use_xrandr = xrandr_major * 100 + xrandr_minor; | ||
659 | saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); | ||
660 | } | ||
661 | } | ||
662 | #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | ||
663 | |||
664 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
665 | /* XVidMode */ | ||
666 | if ( !use_xrandr && | ||
667 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
668 | (!use_xinerama || xinerama_info.screen_number == -1) && | ||
669 | #endif | ||
670 | CheckVidMode(this, &vm_major, &vm_minor) && | ||
671 | SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) | ||
672 | { | ||
673 | #ifdef X11MODES_DEBUG | ||
674 | printf("VidMode modes: (unsorted)\n"); | ||
675 | for ( i = 0; i < nmodes; ++i ) { | ||
676 | printf("Mode %d: %d x %d @ %d\n", i, | ||
677 | modes[i]->hdisplay, modes[i]->vdisplay, | ||
678 | (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 ); | ||
679 | } | ||
680 | #endif | ||
681 | if ( SDL_modelist ) { | ||
682 | for ( i = 0; SDL_modelist[i]; ++i ) { | ||
683 | SDL_free(SDL_modelist[i]); | ||
684 | } | ||
685 | SDL_free(SDL_modelist); | ||
686 | } | ||
687 | SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *)); | ||
688 | if ( !SDL_modelist ) { | ||
689 | SDL_OutOfMemory(); | ||
690 | return -1; | ||
691 | } | ||
692 | SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes); | ||
693 | n = 0; | ||
694 | for ( i=0; i<nmodes; ++i ) { | ||
695 | int w, h; | ||
696 | |||
697 | /* Eliminate duplicate modes with different refresh rates */ | ||
698 | if ( i > 0 && | ||
699 | modes[i]->hdisplay == modes[i-1]->hdisplay && | ||
700 | modes[i]->vdisplay == modes[i-1]->vdisplay ) { | ||
701 | continue; | ||
702 | } | ||
703 | |||
704 | /* Check to see if we should add the screen size (Xinerama) */ | ||
705 | w = modes[i]->hdisplay; | ||
706 | h = modes[i]->vdisplay; | ||
707 | if ( (screen_w * screen_h) >= (w * h) ) { | ||
708 | if ( (screen_w != w) || (screen_h != h) ) { | ||
709 | SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | ||
710 | if ( SDL_modelist[n] ) { | ||
711 | SDL_modelist[n]->x = 0; | ||
712 | SDL_modelist[n]->y = 0; | ||
713 | SDL_modelist[n]->w = screen_w; | ||
714 | SDL_modelist[n]->h = screen_h; | ||
715 | ++n; | ||
716 | } | ||
717 | } | ||
718 | screen_w = 0; | ||
719 | screen_h = 0; | ||
720 | } | ||
721 | |||
722 | /* Add the size from the video mode list */ | ||
723 | SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | ||
724 | if ( SDL_modelist[n] == NULL ) { | ||
725 | break; | ||
726 | } | ||
727 | SDL_modelist[n]->x = 0; | ||
728 | SDL_modelist[n]->y = 0; | ||
729 | SDL_modelist[n]->w = w; | ||
730 | SDL_modelist[n]->h = h; | ||
731 | ++n; | ||
732 | } | ||
733 | SDL_modelist[n] = NULL; | ||
734 | XFree(modes); | ||
735 | |||
736 | use_vidmode = vm_major * 100 + vm_minor; | ||
737 | save_mode(this); | ||
738 | } | ||
739 | #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | ||
740 | |||
741 | #if SDL_VIDEO_DRIVER_X11_XME | ||
742 | /* XiG */ | ||
743 | modelist = NULL; | ||
744 | /* first lets make sure we have the extension, and it's at least v2.0 */ | ||
745 | if ( CheckXME(this, &xme_major, &xme_minor) && xme_major >= 2 && | ||
746 | (nummodes = XiGMiscQueryResolutions(SDL_Display, SDL_Screen, | ||
747 | 0, /* view */ | ||
748 | &ractive, &modelist)) > 1 ) | ||
749 | { /* then we actually have some */ | ||
750 | int j; | ||
751 | |||
752 | /* We get the list already sorted in descending order. | ||
753 | We'll copy it in reverse order so SDL is happy */ | ||
754 | #ifdef X11MODES_DEBUG | ||
755 | fprintf(stderr, "XME: nummodes = %d, active mode = %d\n", | ||
756 | nummodes, ractive); | ||
757 | #endif | ||
758 | if ( SDL_modelist ) { | ||
759 | for ( i = 0; SDL_modelist[i]; ++i ) { | ||
760 | SDL_free(SDL_modelist[i]); | ||
761 | } | ||
762 | SDL_free(SDL_modelist); | ||
763 | } | ||
764 | SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *)); | ||
765 | if ( !SDL_modelist ) { | ||
766 | SDL_OutOfMemory(); | ||
767 | return -1; | ||
768 | } | ||
769 | for ( i=0, j=nummodes-1; j>=0; i++, j-- ) { | ||
770 | if ((SDL_modelist[i] = | ||
771 | (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL) | ||
772 | break; | ||
773 | #ifdef X11MODES_DEBUG | ||
774 | fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n", | ||
775 | i, modelist[i].width, modelist[i].height); | ||
776 | #endif | ||
777 | |||
778 | SDL_modelist[i]->x = 0; | ||
779 | SDL_modelist[i]->y = 0; | ||
780 | SDL_modelist[i]->w = modelist[j].width; | ||
781 | SDL_modelist[i]->h = modelist[j].height; | ||
782 | |||
783 | } | ||
784 | SDL_modelist[i] = NULL; /* terminator */ | ||
785 | |||
786 | use_xme = xme_major * 100 + xme_minor; | ||
787 | saved_res = modelist[ractive]; /* save the current resolution */ | ||
788 | } | ||
789 | if ( modelist ) { | ||
790 | XFree(modelist); | ||
791 | } | ||
792 | #endif /* SDL_VIDEO_DRIVER_X11_XME */ | ||
793 | |||
794 | { | ||
795 | /* It's interesting to note that if we allow 32 bit depths, | ||
796 | we get a visual with an alpha mask on composite servers. | ||
797 | static int depth_list[] = { 32, 24, 16, 15, 8 }; | ||
798 | */ | ||
799 | static int depth_list[] = { 24, 16, 15, 8 }; | ||
800 | int j, np; | ||
801 | int use_directcolor = 1; | ||
802 | XPixmapFormatValues *pf; | ||
803 | |||
804 | /* Search for the visuals in deepest-first order, so that the first | ||
805 | will be the richest one */ | ||
806 | if ( SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { | ||
807 | use_directcolor = 0; | ||
808 | } | ||
809 | this->hidden->nvisuals = 0; | ||
810 | if ( ! add_visual_byid(this, SDL_getenv("SDL_VIDEO_X11_VISUALID")) ) { | ||
811 | for ( i=0; i<SDL_arraysize(depth_list); ++i ) { | ||
812 | if ( depth_list[i] > 8 ) { | ||
813 | if ( use_directcolor ) { | ||
814 | add_visual(this, depth_list[i], DirectColor); | ||
815 | } | ||
816 | add_visual(this, depth_list[i], TrueColor); | ||
817 | } else { | ||
818 | add_visual(this, depth_list[i], PseudoColor); | ||
819 | add_visual(this, depth_list[i], StaticColor); | ||
820 | } | ||
821 | } | ||
822 | add_default_visual(this); | ||
823 | } | ||
824 | if ( this->hidden->nvisuals == 0 ) { | ||
825 | SDL_SetError("Found no sufficiently capable X11 visuals"); | ||
826 | return -1; | ||
827 | } | ||
828 | |||
829 | /* look up the pixel quantum for each depth */ | ||
830 | pf = XListPixmapFormats(SDL_Display, &np); | ||
831 | for(i = 0; i < this->hidden->nvisuals; i++) { | ||
832 | int d = this->hidden->visuals[i].depth; | ||
833 | for(j = 0; j < np; j++) | ||
834 | if(pf[j].depth == d) | ||
835 | break; | ||
836 | this->hidden->visuals[i].bpp = j < np ? pf[j].bits_per_pixel : d; | ||
837 | } | ||
838 | |||
839 | XFree(pf); | ||
840 | } | ||
841 | |||
842 | if ( SDL_modelist == NULL ) { | ||
843 | SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *)); | ||
844 | if ( !SDL_modelist ) { | ||
845 | SDL_OutOfMemory(); | ||
846 | return -1; | ||
847 | } | ||
848 | n = 0; | ||
849 | SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | ||
850 | if ( SDL_modelist[n] ) { | ||
851 | SDL_modelist[n]->x = 0; | ||
852 | SDL_modelist[n]->y = 0; | ||
853 | SDL_modelist[n]->w = screen_w; | ||
854 | SDL_modelist[n]->h = screen_h; | ||
855 | ++n; | ||
856 | } | ||
857 | SDL_modelist[n] = NULL; | ||
858 | } | ||
859 | |||
860 | #ifdef X11MODES_DEBUG | ||
861 | if ( use_xinerama ) { | ||
862 | printf("Xinerama is enabled\n"); | ||
863 | } | ||
864 | |||
865 | if ( use_xrandr ) { | ||
866 | printf("XRandR is enabled\n"); | ||
867 | } | ||
868 | |||
869 | if ( use_vidmode ) { | ||
870 | printf("VidMode is enabled\n"); | ||
871 | } | ||
872 | |||
873 | if ( use_xme ) { | ||
874 | printf("Xi Graphics XME fullscreen is enabled\n"); | ||
875 | } | ||
876 | |||
877 | if ( SDL_modelist ) { | ||
878 | printf("X11 video mode list:\n"); | ||
879 | for ( i=0; SDL_modelist[i]; ++i ) { | ||
880 | printf("\t%dx%d\n", SDL_modelist[i]->w, SDL_modelist[i]->h); | ||
881 | } | ||
882 | } | ||
883 | #endif /* X11MODES_DEBUG */ | ||
884 | |||
885 | return 0; | ||
886 | } | ||
887 | |||
888 | int X11_SupportedVisual(_THIS, SDL_PixelFormat *format) | ||
889 | { | ||
890 | int i; | ||
891 | for(i = 0; i < this->hidden->nvisuals; i++) | ||
892 | if(this->hidden->visuals[i].bpp == format->BitsPerPixel) | ||
893 | return 1; | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | ||
898 | { | ||
899 | if ( X11_SupportedVisual(this, format) ) { | ||
900 | if ( flags & SDL_FULLSCREEN ) { | ||
901 | return(SDL_modelist); | ||
902 | } else { | ||
903 | return((SDL_Rect **)-1); | ||
904 | } | ||
905 | } else { | ||
906 | return((SDL_Rect **)0); | ||
907 | } | ||
908 | } | ||
909 | |||
910 | void X11_FreeVideoModes(_THIS) | ||
911 | { | ||
912 | int i; | ||
913 | |||
914 | if ( SDL_modelist ) { | ||
915 | for ( i=0; SDL_modelist[i]; ++i ) { | ||
916 | SDL_free(SDL_modelist[i]); | ||
917 | } | ||
918 | SDL_free(SDL_modelist); | ||
919 | SDL_modelist = NULL; | ||
920 | } | ||
921 | |||
922 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
923 | /* Free the Xrandr screen configuration */ | ||
924 | if ( screen_config ) { | ||
925 | XRRFreeScreenConfigInfo(screen_config); | ||
926 | screen_config = NULL; | ||
927 | } | ||
928 | #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | ||
929 | } | ||
930 | |||
931 | int X11_ResizeFullScreen(_THIS) | ||
932 | { | ||
933 | int x = 0, y = 0; | ||
934 | int real_w, real_h; | ||
935 | int screen_w; | ||
936 | int screen_h; | ||
937 | |||
938 | screen_w = DisplayWidth(SDL_Display, SDL_Screen); | ||
939 | screen_h = DisplayHeight(SDL_Display, SDL_Screen); | ||
940 | |||
941 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
942 | if ( use_xinerama && | ||
943 | window_w <= xinerama_info.width && | ||
944 | window_h <= xinerama_info.height ) { | ||
945 | x = xinerama_info.x_org; | ||
946 | y = xinerama_info.y_org; | ||
947 | } | ||
948 | #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | ||
949 | |||
950 | if ( currently_fullscreen ) { | ||
951 | /* Switch resolution and cover it with the FSwindow */ | ||
952 | move_cursor_to(this, x, y); | ||
953 | set_best_resolution(this, window_w, window_h); | ||
954 | move_cursor_to(this, x, y); | ||
955 | get_real_resolution(this, &real_w, &real_h); | ||
956 | if ( window_w > real_w ) { | ||
957 | real_w = MAX(real_w, screen_w); | ||
958 | } | ||
959 | if ( window_h > real_h ) { | ||
960 | real_h = MAX(real_h, screen_h); | ||
961 | } | ||
962 | XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h); | ||
963 | move_cursor_to(this, real_w/2, real_h/2); | ||
964 | |||
965 | /* Center and reparent the drawing window */ | ||
966 | x = (real_w - window_w)/2; | ||
967 | y = (real_h - window_h)/2; | ||
968 | XReparentWindow(SDL_Display, SDL_Window, FSwindow, x, y); | ||
969 | /* FIXME: move the mouse to the old relative location */ | ||
970 | XSync(SDL_Display, True); /* Flush spurious mode change events */ | ||
971 | } | ||
972 | return(1); | ||
973 | } | ||
974 | |||
975 | void X11_QueueEnterFullScreen(_THIS) | ||
976 | { | ||
977 | switch_waiting = 0x01 | SDL_FULLSCREEN; | ||
978 | switch_time = SDL_GetTicks() + 1500; | ||
979 | #if 0 /* This causes a BadMatch error if the window is iconified (not needed) */ | ||
980 | XSetInputFocus(SDL_Display, WMwindow, RevertToNone, CurrentTime); | ||
981 | #endif | ||
982 | } | ||
983 | |||
984 | int X11_EnterFullScreen(_THIS) | ||
985 | { | ||
986 | int okay; | ||
987 | #if 0 | ||
988 | Window tmpwin, *windows; | ||
989 | int i, nwindows; | ||
990 | #endif | ||
991 | int x = 0, y = 0; | ||
992 | int real_w, real_h; | ||
993 | int screen_w; | ||
994 | int screen_h; | ||
995 | |||
996 | okay = 1; | ||
997 | if ( currently_fullscreen ) { | ||
998 | return(okay); | ||
999 | } | ||
1000 | |||
1001 | /* Ungrab the input so that we can move the mouse around */ | ||
1002 | X11_GrabInputNoLock(this, SDL_GRAB_OFF); | ||
1003 | |||
1004 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
1005 | if ( use_xinerama && | ||
1006 | window_w <= xinerama_info.width && | ||
1007 | window_h <= xinerama_info.height ) { | ||
1008 | x = xinerama_info.x_org; | ||
1009 | y = xinerama_info.y_org; | ||
1010 | } | ||
1011 | #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | ||
1012 | |||
1013 | /* Map the fullscreen window to blank the screen */ | ||
1014 | screen_w = DisplayWidth(SDL_Display, SDL_Screen); | ||
1015 | screen_h = DisplayHeight(SDL_Display, SDL_Screen); | ||
1016 | get_real_resolution(this, &real_w, &real_h); | ||
1017 | real_w = MAX(window_w, MAX(real_w, screen_w)); | ||
1018 | real_h = MAX(window_h, MAX(real_h, screen_h)); | ||
1019 | XMoveResizeWindow(SDL_Display, FSwindow, | ||
1020 | x, y, real_w, real_h); | ||
1021 | XMapRaised(SDL_Display, FSwindow); | ||
1022 | X11_WaitMapped(this, FSwindow); | ||
1023 | |||
1024 | #if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */ | ||
1025 | /* Make sure we got to the top of the window stack */ | ||
1026 | if ( XQueryTree(SDL_Display, SDL_Root, &tmpwin, &tmpwin, | ||
1027 | &windows, &nwindows) && windows ) { | ||
1028 | /* If not, try to put us there - if fail... oh well */ | ||
1029 | if ( windows[nwindows-1] != FSwindow ) { | ||
1030 | tmpwin = windows[nwindows-1]; | ||
1031 | for ( i=0; i<nwindows; ++i ) { | ||
1032 | if ( windows[i] == FSwindow ) { | ||
1033 | SDL_memcpy(&windows[i], &windows[i+1], | ||
1034 | (nwindows-i-1)*sizeof(windows[i])); | ||
1035 | break; | ||
1036 | } | ||
1037 | } | ||
1038 | windows[nwindows-1] = FSwindow; | ||
1039 | XRestackWindows(SDL_Display, windows, nwindows); | ||
1040 | XSync(SDL_Display, False); | ||
1041 | } | ||
1042 | XFree(windows); | ||
1043 | } | ||
1044 | #else | ||
1045 | XRaiseWindow(SDL_Display, FSwindow); | ||
1046 | #endif | ||
1047 | |||
1048 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
1049 | /* Save the current video mode */ | ||
1050 | if ( use_vidmode ) { | ||
1051 | SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, True); | ||
1052 | save_mode(this); | ||
1053 | } | ||
1054 | #endif | ||
1055 | currently_fullscreen = 1; | ||
1056 | |||
1057 | /* Set the new resolution */ | ||
1058 | okay = X11_ResizeFullScreen(this); | ||
1059 | if ( ! okay ) { | ||
1060 | X11_LeaveFullScreen(this); | ||
1061 | } | ||
1062 | /* Set the colormap */ | ||
1063 | if ( SDL_XColorMap ) { | ||
1064 | XInstallColormap(SDL_Display, SDL_XColorMap); | ||
1065 | } | ||
1066 | if ( okay ) { | ||
1067 | X11_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN); | ||
1068 | } | ||
1069 | |||
1070 | /* We may need to refresh the screen at this point (no backing store) | ||
1071 | We also don't get an event, which is why we explicitly refresh. */ | ||
1072 | if ( this->screen ) { | ||
1073 | if ( this->screen->flags & SDL_OPENGL ) { | ||
1074 | SDL_PrivateExpose(); | ||
1075 | } else { | ||
1076 | X11_RefreshDisplay(this); | ||
1077 | } | ||
1078 | } | ||
1079 | |||
1080 | return(okay); | ||
1081 | } | ||
1082 | |||
1083 | int X11_LeaveFullScreen(_THIS) | ||
1084 | { | ||
1085 | if ( currently_fullscreen ) { | ||
1086 | XReparentWindow(SDL_Display, SDL_Window, WMwindow, 0, 0); | ||
1087 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
1088 | if ( use_vidmode ) { | ||
1089 | restore_mode(this); | ||
1090 | SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, False); | ||
1091 | } | ||
1092 | #endif | ||
1093 | |||
1094 | #if SDL_VIDEO_DRIVER_X11_XME | ||
1095 | if ( use_xme ) { | ||
1096 | int rw, rh; | ||
1097 | |||
1098 | /* check current mode so we can avoid uneccessary mode changes */ | ||
1099 | get_real_resolution(this, &rw, &rh); | ||
1100 | |||
1101 | if (rw != saved_res.width || rh != saved_res.height) { | ||
1102 | XiGMiscChangeResolution(SDL_Display, | ||
1103 | SDL_Screen, | ||
1104 | 0, /* view */ | ||
1105 | saved_res.width, | ||
1106 | saved_res.height, | ||
1107 | 0); | ||
1108 | XSync(SDL_Display, False); | ||
1109 | } | ||
1110 | } | ||
1111 | #endif | ||
1112 | |||
1113 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
1114 | if ( use_xrandr ) { | ||
1115 | XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root, | ||
1116 | saved_size_id, saved_rotation, CurrentTime); | ||
1117 | } | ||
1118 | #endif | ||
1119 | |||
1120 | XUnmapWindow(SDL_Display, FSwindow); | ||
1121 | X11_WaitUnmapped(this, FSwindow); | ||
1122 | XSync(SDL_Display, True); /* Flush spurious mode change events */ | ||
1123 | currently_fullscreen = 0; | ||
1124 | } | ||
1125 | /* If we get popped out of fullscreen mode for some reason, input_grab | ||
1126 | will still have the SDL_GRAB_FULLSCREEN flag set, since this is only | ||
1127 | temporary. In this case, release the grab unless the input has been | ||
1128 | explicitly grabbed. | ||
1129 | */ | ||
1130 | X11_GrabInputNoLock(this, this->input_grab & ~SDL_GRAB_FULLSCREEN); | ||
1131 | |||
1132 | /* We may need to refresh the screen at this point (no backing store) | ||
1133 | We also don't get an event, which is why we explicitly refresh. */ | ||
1134 | if ( this->screen ) { | ||
1135 | if ( this->screen->flags & SDL_OPENGL ) { | ||
1136 | SDL_PrivateExpose(); | ||
1137 | } else { | ||
1138 | X11_RefreshDisplay(this); | ||
1139 | } | ||
1140 | } | ||
1141 | |||
1142 | return(0); | ||
1143 | } | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11modes_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11modes_c.h deleted file mode 100644 index f7780bf213..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11modes_c.h +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Utilities for getting and setting the X display mode */ | ||
25 | |||
26 | #include "SDL_x11video.h" | ||
27 | |||
28 | /* Define this if you want to grab the keyboard in fullscreen mode. | ||
29 | If you do not define this, SDL will return from SDL_SetVideoMode() | ||
30 | immediately, but will not actually go fullscreen until the window | ||
31 | manager is idle. | ||
32 | */ | ||
33 | #define GRAB_FULLSCREEN | ||
34 | |||
35 | extern int X11_GetVideoModes(_THIS); | ||
36 | extern SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | ||
37 | extern void X11_FreeVideoModes(_THIS); | ||
38 | extern int X11_ResizeFullScreen(_THIS); | ||
39 | extern void X11_WaitMapped(_THIS, Window win); | ||
40 | extern void X11_WaitUnmapped(_THIS, Window win); | ||
41 | extern void X11_QueueEnterFullScreen(_THIS); | ||
42 | extern int X11_EnterFullScreen(_THIS); | ||
43 | extern int X11_LeaveFullScreen(_THIS); | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11mouse.c b/apps/plugins/sdl/src/video/x11/SDL_x11mouse.c deleted file mode 100644 index 16ad739195..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11mouse.c +++ /dev/null | |||
@@ -1,288 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <X11/Xlib.h> | ||
25 | #include <X11/Xutil.h> | ||
26 | |||
27 | #include "SDL_mouse.h" | ||
28 | #include "../../events/SDL_events_c.h" | ||
29 | #include "../SDL_cursor_c.h" | ||
30 | #include "SDL_x11dga_c.h" | ||
31 | #include "SDL_x11mouse_c.h" | ||
32 | |||
33 | |||
34 | /* The implementation dependent data for the window manager cursor */ | ||
35 | struct WMcursor { | ||
36 | Cursor x_cursor; | ||
37 | }; | ||
38 | |||
39 | |||
40 | void X11_FreeWMCursor(_THIS, WMcursor *cursor) | ||
41 | { | ||
42 | if ( SDL_Display != NULL ) { | ||
43 | SDL_Lock_EventThread(); | ||
44 | XFreeCursor(SDL_Display, cursor->x_cursor); | ||
45 | XSync(SDL_Display, False); | ||
46 | SDL_Unlock_EventThread(); | ||
47 | } | ||
48 | SDL_free(cursor); | ||
49 | } | ||
50 | |||
51 | WMcursor *X11_CreateWMCursor(_THIS, | ||
52 | Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) | ||
53 | { | ||
54 | WMcursor *cursor; | ||
55 | XGCValues GCvalues; | ||
56 | GC GCcursor; | ||
57 | XImage *data_image, *mask_image; | ||
58 | Pixmap data_pixmap, mask_pixmap; | ||
59 | int clen, i; | ||
60 | char *x_data, *x_mask; | ||
61 | static XColor black = { 0, 0, 0, 0 }; | ||
62 | static XColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; | ||
63 | |||
64 | /* Allocate the cursor memory */ | ||
65 | cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor)); | ||
66 | if ( cursor == NULL ) { | ||
67 | SDL_OutOfMemory(); | ||
68 | return(NULL); | ||
69 | } | ||
70 | |||
71 | /* Mix the mask and the data */ | ||
72 | clen = (w/8)*h; | ||
73 | x_data = (char *)SDL_malloc(clen); | ||
74 | if ( x_data == NULL ) { | ||
75 | SDL_free(cursor); | ||
76 | SDL_OutOfMemory(); | ||
77 | return(NULL); | ||
78 | } | ||
79 | x_mask = (char *)SDL_malloc(clen); | ||
80 | if ( x_mask == NULL ) { | ||
81 | SDL_free(cursor); | ||
82 | SDL_free(x_data); | ||
83 | SDL_OutOfMemory(); | ||
84 | return(NULL); | ||
85 | } | ||
86 | for ( i=0; i<clen; ++i ) { | ||
87 | /* The mask is OR'd with the data to turn inverted color | ||
88 | pixels black since inverted color cursors aren't supported | ||
89 | under X11. | ||
90 | */ | ||
91 | x_mask[i] = data[i] | mask[i]; | ||
92 | x_data[i] = data[i]; | ||
93 | } | ||
94 | |||
95 | /* Prevent the event thread from running while we use the X server */ | ||
96 | SDL_Lock_EventThread(); | ||
97 | |||
98 | /* Create the data image */ | ||
99 | data_image = XCreateImage(SDL_Display, | ||
100 | DefaultVisual(SDL_Display, SDL_Screen), | ||
101 | 1, XYBitmap, 0, x_data, w, h, 8, w/8); | ||
102 | data_image->byte_order = MSBFirst; | ||
103 | data_image->bitmap_bit_order = MSBFirst; | ||
104 | data_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1); | ||
105 | |||
106 | /* Create the data mask */ | ||
107 | mask_image = XCreateImage(SDL_Display, | ||
108 | DefaultVisual(SDL_Display, SDL_Screen), | ||
109 | 1, XYBitmap, 0, x_mask, w, h, 8, w/8); | ||
110 | mask_image->byte_order = MSBFirst; | ||
111 | mask_image->bitmap_bit_order = MSBFirst; | ||
112 | mask_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1); | ||
113 | |||
114 | /* Create the graphics context */ | ||
115 | GCvalues.function = GXcopy; | ||
116 | GCvalues.foreground = ~0; | ||
117 | GCvalues.background = 0; | ||
118 | GCvalues.plane_mask = AllPlanes; | ||
119 | GCcursor = XCreateGC(SDL_Display, data_pixmap, | ||
120 | (GCFunction|GCForeground|GCBackground|GCPlaneMask), | ||
121 | &GCvalues); | ||
122 | |||
123 | /* Blit the images to the pixmaps */ | ||
124 | XPutImage(SDL_Display, data_pixmap, GCcursor, data_image, | ||
125 | 0, 0, 0, 0, w, h); | ||
126 | XPutImage(SDL_Display, mask_pixmap, GCcursor, mask_image, | ||
127 | 0, 0, 0, 0, w, h); | ||
128 | XFreeGC(SDL_Display, GCcursor); | ||
129 | /* These free the x_data and x_mask memory pointers */ | ||
130 | XDestroyImage(data_image); | ||
131 | XDestroyImage(mask_image); | ||
132 | |||
133 | /* Create the cursor */ | ||
134 | cursor->x_cursor = XCreatePixmapCursor(SDL_Display, data_pixmap, | ||
135 | mask_pixmap, &black, &white, hot_x, hot_y); | ||
136 | XFreePixmap(SDL_Display, data_pixmap); | ||
137 | XFreePixmap(SDL_Display, mask_pixmap); | ||
138 | |||
139 | /* Release the event thread */ | ||
140 | XSync(SDL_Display, False); | ||
141 | SDL_Unlock_EventThread(); | ||
142 | |||
143 | return(cursor); | ||
144 | } | ||
145 | |||
146 | int X11_ShowWMCursor(_THIS, WMcursor *cursor) | ||
147 | { | ||
148 | /* Don't do anything if the display is gone */ | ||
149 | if ( SDL_Display == NULL ) { | ||
150 | return(0); | ||
151 | } | ||
152 | |||
153 | /* Set the X11 cursor cursor, or blank if cursor is NULL */ | ||
154 | if ( SDL_Window ) { | ||
155 | SDL_Lock_EventThread(); | ||
156 | if ( cursor == NULL ) { | ||
157 | if ( SDL_BlankCursor != NULL ) { | ||
158 | XDefineCursor(SDL_Display, SDL_Window, | ||
159 | SDL_BlankCursor->x_cursor); | ||
160 | } | ||
161 | } else { | ||
162 | XDefineCursor(SDL_Display, SDL_Window, cursor->x_cursor); | ||
163 | } | ||
164 | XSync(SDL_Display, False); | ||
165 | SDL_Unlock_EventThread(); | ||
166 | } | ||
167 | return(1); | ||
168 | } | ||
169 | |||
170 | void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | ||
171 | { | ||
172 | if ( using_dga & DGA_MOUSE ) { | ||
173 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
174 | } else if ( mouse_relative) { | ||
175 | /* RJR: March 28, 2000 | ||
176 | leave physical cursor at center of screen if | ||
177 | mouse hidden and grabbed */ | ||
178 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
179 | } else { | ||
180 | SDL_Lock_EventThread(); | ||
181 | XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, x, y); | ||
182 | XSync(SDL_Display, False); | ||
183 | SDL_Unlock_EventThread(); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /* Sets the mouse acceleration from a string of the form: | ||
188 | 2/1/0 | ||
189 | The first number is the numerator, followed by the acceleration | ||
190 | denumenator and threshold. | ||
191 | */ | ||
192 | static void SetMouseAccel(_THIS, const char *accel_param) | ||
193 | { | ||
194 | int i; | ||
195 | size_t len; | ||
196 | int accel_value[3]; | ||
197 | char *mouse_param, *mouse_param_buf, *pin; | ||
198 | |||
199 | len = SDL_strlen(accel_param)+1; | ||
200 | mouse_param_buf = SDL_stack_alloc(char, len); | ||
201 | if ( ! mouse_param_buf ) { | ||
202 | return; | ||
203 | } | ||
204 | SDL_strlcpy(mouse_param_buf, accel_param, len); | ||
205 | mouse_param = mouse_param_buf; | ||
206 | |||
207 | for ( i=0; (i < 3) && mouse_param; ++i ) { | ||
208 | pin = SDL_strchr(mouse_param, '/'); | ||
209 | if ( pin ) { | ||
210 | *pin = '\0'; | ||
211 | } | ||
212 | accel_value[i] = atoi(mouse_param); | ||
213 | if ( pin ) { | ||
214 | mouse_param = pin+1; | ||
215 | } else { | ||
216 | mouse_param = NULL; | ||
217 | } | ||
218 | } | ||
219 | if ( i == 3 ) { | ||
220 | XChangePointerControl(SDL_Display, True, True, | ||
221 | accel_value[0], accel_value[1], accel_value[2]); | ||
222 | } | ||
223 | SDL_stack_free(mouse_param_buf); | ||
224 | } | ||
225 | |||
226 | /* Check to see if we need to enter or leave mouse relative mode */ | ||
227 | void X11_CheckMouseModeNoLock(_THIS) | ||
228 | { | ||
229 | const Uint8 full_focus = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); | ||
230 | char *env_override; | ||
231 | int enable_relative = 1; | ||
232 | |||
233 | /* This happens when quiting after an xio error */ | ||
234 | if ( SDL_Display == NULL ) | ||
235 | return; | ||
236 | |||
237 | /* Allow the user to override the relative mouse mode. | ||
238 | They almost never want to do this, as it seriously affects | ||
239 | applications that rely on continuous relative mouse motion. | ||
240 | */ | ||
241 | env_override = SDL_getenv("SDL_MOUSE_RELATIVE"); | ||
242 | if ( env_override ) { | ||
243 | enable_relative = atoi(env_override); | ||
244 | } | ||
245 | |||
246 | /* If the mouse is hidden and input is grabbed, we use relative mode */ | ||
247 | if ( enable_relative && | ||
248 | !(SDL_cursorstate & CURSOR_VISIBLE) && | ||
249 | (this->input_grab != SDL_GRAB_OFF) && | ||
250 | (SDL_GetAppState() & full_focus) == full_focus ) { | ||
251 | if ( ! mouse_relative ) { | ||
252 | X11_EnableDGAMouse(this); | ||
253 | if ( ! (using_dga & DGA_MOUSE) ) { | ||
254 | char *xmouse_accel; | ||
255 | |||
256 | SDL_GetMouseState(&mouse_last.x, &mouse_last.y); | ||
257 | /* Use as raw mouse mickeys as possible */ | ||
258 | XGetPointerControl(SDL_Display, | ||
259 | &mouse_accel.numerator, | ||
260 | &mouse_accel.denominator, | ||
261 | &mouse_accel.threshold); | ||
262 | xmouse_accel=SDL_getenv("SDL_VIDEO_X11_MOUSEACCEL"); | ||
263 | if ( xmouse_accel ) { | ||
264 | SetMouseAccel(this, xmouse_accel); | ||
265 | } | ||
266 | } | ||
267 | mouse_relative = 1; | ||
268 | } | ||
269 | } else { | ||
270 | if ( mouse_relative ) { | ||
271 | if ( using_dga & DGA_MOUSE ) { | ||
272 | X11_DisableDGAMouse(this); | ||
273 | } else { | ||
274 | XChangePointerControl(SDL_Display, True, True, | ||
275 | mouse_accel.numerator, | ||
276 | mouse_accel.denominator, | ||
277 | mouse_accel.threshold); | ||
278 | } | ||
279 | mouse_relative = 0; | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | void X11_CheckMouseMode(_THIS) | ||
284 | { | ||
285 | SDL_Lock_EventThread(); | ||
286 | X11_CheckMouseModeNoLock(this); | ||
287 | SDL_Unlock_EventThread(); | ||
288 | } | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11mouse_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11mouse_c.h deleted file mode 100644 index 03d97d86f6..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11mouse_c.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_x11video.h" | ||
25 | |||
26 | /* Functions to be exported */ | ||
27 | extern void X11_FreeWMCursor(_THIS, WMcursor *cursor); | ||
28 | extern WMcursor *X11_CreateWMCursor(_THIS, | ||
29 | Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); | ||
30 | extern int X11_ShowWMCursor(_THIS, WMcursor *cursor); | ||
31 | extern void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y); | ||
32 | extern void X11_CheckMouseModeNoLock(_THIS); | ||
33 | extern void X11_CheckMouseMode(_THIS); | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11sym.h b/apps/plugins/sdl/src/video/x11/SDL_x11sym.h deleted file mode 100644 index 4875b989c9..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11sym.h +++ /dev/null | |||
@@ -1,201 +0,0 @@ | |||
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 | |||
23 | SDL_X11_MODULE(BASEXLIB) | ||
24 | SDL_X11_SYM(XClassHint*,XAllocClassHint,(void),(),return) | ||
25 | SDL_X11_SYM(Status,XAllocColor,(Display* a,Colormap b,XColor* c),(a,b,c),return) | ||
26 | SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return) | ||
27 | SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return) | ||
28 | SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return) | ||
29 | SDL_X11_SYM(int,XChangeProperty,(Display* a,Window b,Atom c,Atom d,int e,int f,_Xconst unsigned char* g,int h),(a,b,c,d,e,f,g,h),return) | ||
30 | SDL_X11_SYM(int,XChangeWindowAttributes,(Display* a,Window b,unsigned long c,XSetWindowAttributes* d),(a,b,c,d),return) | ||
31 | SDL_X11_SYM(Bool,XCheckTypedEvent,(Display* a,int b,XEvent* c),(a,b,c),return) | ||
32 | SDL_X11_SYM(int,XClearWindow,(Display* a,Window b),(a,b),return) | ||
33 | SDL_X11_SYM(int,XCloseDisplay,(Display* a),(a),return) | ||
34 | SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return) | ||
35 | SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,XColor* e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return) | ||
36 | SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return) | ||
37 | SDL_X11_SYM(XImage*,XCreateImage,(Display* a,Visual* b,unsigned int c,int d,int e,char* f,unsigned int g,unsigned int h,int i,int j),(a,b,c,d,e,f,g,h,i,j),return) | ||
38 | SDL_X11_SYM(Pixmap,XCreatePixmap,(Display* a,Drawable b,unsigned int c,unsigned int d,unsigned int e),(a,b,c,d,e),return) | ||
39 | SDL_X11_SYM(Pixmap,XCreatePixmapFromBitmapData,(Display* a,Drawable b,char* c,unsigned int d,unsigned int e,unsigned long f,unsigned long g,unsigned int h),(a,b,c,d,e,f,g,h),return) | ||
40 | SDL_X11_SYM(Window,XCreateSimpleWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,unsigned long h,unsigned long i),(a,b,c,d,e,f,g,h,i),return) | ||
41 | SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l),(a,b,c,d,e,f,g,h,i,j,k,l),return) | ||
42 | SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c),(a,b,c),return) | ||
43 | SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c),(a,b,c),return) | ||
44 | SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b),(a,b),return) | ||
45 | SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a),(a),return) | ||
46 | SDL_X11_SYM(int,XEventsQueued,(Display* a,int b),(a,b),return) | ||
47 | SDL_X11_SYM(Bool,XFilterEvent,(XEvent *event, Window w),(event,w),return) | ||
48 | SDL_X11_SYM(int,XFlush,(Display* a),(a),return) | ||
49 | SDL_X11_SYM(int,XFree,(void*a),(a),return) | ||
50 | SDL_X11_SYM(int,XFreeColormap,(Display* a,Colormap b),(a,b),return) | ||
51 | SDL_X11_SYM(int,XFreeColors,(Display* a,Colormap b,unsigned long* c,int d,unsigned long e),(a,b,c,d,e),return) | ||
52 | SDL_X11_SYM(int,XFreeCursor,(Display* a,Cursor b),(a,b),return) | ||
53 | SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return) | ||
54 | SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return) | ||
55 | SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return) | ||
56 | SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return) | ||
57 | SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return) | ||
58 | SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return) | ||
59 | SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return) | ||
60 | SDL_X11_SYM(XWMHints*,XGetWMHints,(Display* a,Window b),(a,b),return) | ||
61 | SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return) | ||
62 | SDL_X11_SYM(int,XGrabKeyboard,(Display* a,Window b,Bool c,int d,int e,Time f),(a,b,c,d,e,f),return) | ||
63 | SDL_X11_SYM(int,XGrabPointer,(Display* a,Window b,Bool c,unsigned int d,int e,int f,Window g,Cursor h,Time i),(a,b,c,d,e,f,g,h,i),return) | ||
64 | SDL_X11_SYM(Status,XIconifyWindow,(Display* a,Window b,int c),(a,b,c),return) | ||
65 | SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return) | ||
66 | SDL_X11_SYM(KeyCode,XKeysymToKeycode,(Display* a,KeySym b),(a,b),return) | ||
67 | SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return) | ||
68 | SDL_X11_SYM(XPixmapFormatValues*,XListPixmapFormats,(Display* a,int* b),(a,b),return) | ||
69 | SDL_X11_SYM(int,XLookupString,(XKeyEvent* a,char* b,int c,KeySym* d,XComposeStatus* e),(a,b,c,d,e),return) | ||
70 | SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return) | ||
71 | SDL_X11_SYM(int,XMapWindow,(Display* a,Window b),(a,b),return) | ||
72 | SDL_X11_SYM(int,XMaskEvent,(Display* a,long b,XEvent* c),(a,b,c),return) | ||
73 | SDL_X11_SYM(Status,XMatchVisualInfo,(Display* a,int b,int c,int d,XVisualInfo* e),(a,b,c,d,e),return) | ||
74 | SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return) | ||
75 | SDL_X11_SYM(int,XMoveResizeWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f),(a,b,c,d,e,f),return) | ||
76 | SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return) | ||
77 | SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return) | ||
78 | SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return) | ||
79 | SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return) | ||
80 | SDL_X11_SYM(int,XPending,(Display* a),(a),return) | ||
81 | SDL_X11_SYM(int,XPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j),(a,b,c,d,e,f,g,h,i,j),return) | ||
82 | SDL_X11_SYM(int,XQueryColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return) | ||
83 | SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return) | ||
84 | SDL_X11_SYM(Bool,XQueryPointer,(Display* a,Window b,Window* c,Window* d,int* e,int* f,int* g,int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return) | ||
85 | SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return) | ||
86 | SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return) | ||
87 | SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return) | ||
88 | SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return) | ||
89 | SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return) | ||
90 | SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return) | ||
91 | SDL_X11_SYM(int,XSetClassHint,(Display* a,Window b,XClassHint* c),(a,b,c),return) | ||
92 | SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return) | ||
93 | SDL_X11_SYM(XIOErrorHandler,XSetIOErrorHandler,(XIOErrorHandler a),(a),return) | ||
94 | SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return) | ||
95 | SDL_X11_SYM(int,XSetWMHints,(Display* a,Window b,XWMHints* c),(a,b,c),return) | ||
96 | SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),) | ||
97 | SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),) | ||
98 | SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return) | ||
99 | SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return) | ||
100 | SDL_X11_SYM(int,XSetWindowBackgroundPixmap,(Display* a,Window b,Pixmap c),(a,b,c),return) | ||
101 | SDL_X11_SYM(int,XSetWindowColormap,(Display* a,Window b,Colormap c),(a,b,c),return) | ||
102 | SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return) | ||
103 | SDL_X11_SYM(Status,XStringListToTextProperty,(char** a,int b,XTextProperty* c),(a,b,c),return) | ||
104 | SDL_X11_SYM(int,XSync,(Display* a,Bool b),(a,b),return) | ||
105 | SDL_X11_SYM(int,XUngrabKeyboard,(Display* a,Time b),(a,b),return) | ||
106 | SDL_X11_SYM(int,XUngrabPointer,(Display* a,Time b),(a,b),return) | ||
107 | SDL_X11_SYM(int,XUnmapWindow,(Display* a,Window b),(a,b),return) | ||
108 | SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned int f,unsigned int g,int h, int i),(a,b,c,d,e,f,g,h,i),return) | ||
109 | SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return) | ||
110 | SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return) | ||
111 | SDL_X11_SYM(XExtensionInfo*,XextCreateExtension,(void),(),return) | ||
112 | SDL_X11_SYM(void,XextDestroyExtension,(XExtensionInfo* a),(a),) | ||
113 | SDL_X11_SYM(XExtDisplayInfo*,XextFindDisplay,(XExtensionInfo* a,Display* b),(a,b),return) | ||
114 | SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo* a,Display* b),(a,b),return) | ||
115 | SDL_X11_SYM(Bool,XQueryExtension,(Display* a,_Xconst char* b,int* c,int* d,int* e),(a,b,c,d,e),return) | ||
116 | SDL_X11_SYM(char *,XDisplayString,(Display* a),(a),return) | ||
117 | SDL_X11_SYM(int,XGetErrorText,(Display* a,int b,char* c,int d),(a,b,c,d),return) | ||
118 | SDL_X11_SYM(void,_XEatData,(Display* a,unsigned long b),(a,b),) | ||
119 | SDL_X11_SYM(void,_XFlush,(Display* a),(a),) | ||
120 | SDL_X11_SYM(void,_XFlushGCCache,(Display* a,GC b),(a,b),) | ||
121 | SDL_X11_SYM(int,_XRead,(Display* a,char* b,long c),(a,b,c),return) | ||
122 | SDL_X11_SYM(void,_XReadPad,(Display* a,char* b,long c),(a,b,c),) | ||
123 | SDL_X11_SYM(void,_XSend,(Display* a,_Xconst char* b,long c),(a,b,c),) | ||
124 | SDL_X11_SYM(Status,_XReply,(Display* a,xReply* b,int c,Bool d),(a,b,c,d),return) | ||
125 | SDL_X11_SYM(unsigned long,_XSetLastRequestRead,(Display* a,xGenericReply* b),(a,b),return) | ||
126 | SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),return) | ||
127 | SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,SDL_X11_XESetWireToEventRetType c),(a,b,c),return) | ||
128 | SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return) | ||
129 | SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return) | ||
130 | |||
131 | #if NeedWidePrototypes | ||
132 | SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return) | ||
133 | #else | ||
134 | SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,KeyCode b,int c),(a,b,c),return) | ||
135 | #endif | ||
136 | |||
137 | #ifdef X_HAVE_UTF8_STRING | ||
138 | SDL_X11_MODULE(UTF8) | ||
139 | SDL_X11_SYM(int,Xutf8TextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return) | ||
140 | SDL_X11_SYM(int,Xutf8LookupString,(XIC a,XKeyPressedEvent* b,char* c,int d,KeySym* e,Status* f),(a,b,c,d,e,f),return) | ||
141 | /*SDL_X11_SYM(XIC,XCreateIC,(XIM, ...),return) !!! ARGH! */ | ||
142 | SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),) | ||
143 | SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),) | ||
144 | SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),) | ||
145 | /*SDL_X11_SYM(char*,XGetICValues,(XIC a, ...),return)*/ | ||
146 | SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return) | ||
147 | SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return) | ||
148 | SDL_X11_SYM(char*,XSetLocaleModifiers,(_Xconst char* a),(a),return) | ||
149 | SDL_X11_SYM(int,XRefreshKeyboardMapping,(XMappingEvent* a),(a),return) | ||
150 | SDL_X11_SYM(Display*,XDisplayOfIM,(XIM a),(a),return) | ||
151 | #endif | ||
152 | |||
153 | #ifndef NO_SHARED_MEMORY | ||
154 | SDL_X11_MODULE(SHM) | ||
155 | SDL_X11_SYM(Status,XShmAttach,(Display* a,XShmSegmentInfo* b),(a,b),return) | ||
156 | SDL_X11_SYM(Status,XShmDetach,(Display* a,XShmSegmentInfo* b),(a,b),return) | ||
157 | SDL_X11_SYM(Status,XShmPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j,Bool k),(a,b,c,d,e,f,g,h,i,j,k),return) | ||
158 | SDL_X11_SYM(XImage*,XShmCreateImage,(Display* a,Visual* b,unsigned int c,int d,char* e,XShmSegmentInfo* f,unsigned int g,unsigned int h),(a,b,c,d,e,f,g,h),return) | ||
159 | SDL_X11_SYM(Bool,XShmQueryExtension,(Display* a),(a),return) | ||
160 | #endif | ||
161 | |||
162 | /* | ||
163 | * Not required...these only exist in code in headers on some 64-bit platforms, | ||
164 | * and are removed via macros elsewhere, so it's safe for them to be missing. | ||
165 | */ | ||
166 | #ifdef LONG64 | ||
167 | SDL_X11_MODULE(IO_32BIT) | ||
168 | SDL_X11_SYM(int,_XData32,(Display *dpy,register long *data,unsigned len),(dpy,data,len),return) | ||
169 | SDL_X11_SYM(void,_XRead32,(Display *dpy,register long *data,long len),(dpy,data,len),) | ||
170 | #endif | ||
171 | |||
172 | /* | ||
173 | * libX11 1.4.99.1 added _XGetRequest, and macros use it behind the scenes. | ||
174 | */ | ||
175 | SDL_X11_MODULE(XGETREQUEST) | ||
176 | SDL_X11_SYM(void *,_XGetRequest,(Display* a,CARD8 b,size_t c),(a,b,c),return) | ||
177 | |||
178 | /* | ||
179 | * These only show up on some variants of Unix. | ||
180 | */ | ||
181 | #if defined(__osf__) | ||
182 | SDL_X11_MODULE(OSF_ENTRY_POINTS) | ||
183 | SDL_X11_SYM(void,_SmtBufferOverflow,(Display *dpy,register smtDisplayPtr p),(dpy,p),) | ||
184 | SDL_X11_SYM(void,_SmtIpError,(Display *dpy,register smtDisplayPtr p, int i),(dpy,p,i),) | ||
185 | SDL_X11_SYM(int,ipAllocateData,(ChannelPtr a, IPCard b, IPDataPtr * c),(a,b,c),return) | ||
186 | SDL_X11_SYM(int,ipUnallocateAndSendData,(ChannelPtr a, IPCard b),(a,b),return) | ||
187 | #endif | ||
188 | |||
189 | /* Xrandr support. */ | ||
190 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
191 | SDL_X11_MODULE(XRANDR) | ||
192 | SDL_X11_SYM(Status,XRRQueryVersion,(Display *dpy,int *major_versionp,int *minor_versionp),(dpy,major_versionp,minor_versionp),return) | ||
193 | SDL_X11_SYM(XRRScreenConfiguration *,XRRGetScreenInfo,(Display *dpy,Drawable draw),(dpy,draw),return) | ||
194 | SDL_X11_SYM(SizeID,XRRConfigCurrentConfiguration,(XRRScreenConfiguration *config,Rotation *rotation),(config,rotation),return) | ||
195 | SDL_X11_SYM(XRRScreenSize *,XRRConfigSizes,(XRRScreenConfiguration *config, int *nsizes),(config,nsizes),return) | ||
196 | SDL_X11_SYM(Status,XRRSetScreenConfig,(Display *dpy, XRRScreenConfiguration *config, Drawable draw, int size_index, Rotation rotation, Time timestamp),(dpy,config,draw,size_index,rotation,timestamp),return) | ||
197 | SDL_X11_SYM(void,XRRFreeScreenConfigInfo,(XRRScreenConfiguration *config),(config),) | ||
198 | #endif | ||
199 | |||
200 | /* end of SDL_x11sym.h ... */ | ||
201 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11video.c b/apps/plugins/sdl/src/video/x11/SDL_x11video.c deleted file mode 100644 index f7d80732c0..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11video.c +++ /dev/null | |||
@@ -1,1571 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* X11 based SDL video driver implementation. | ||
25 | Note: This implementation does not currently need X11 thread locking, | ||
26 | since the event thread uses a separate X connection and any | ||
27 | additional locking necessary is handled internally. However, | ||
28 | if full locking is neccessary, take a look at XInitThreads(). | ||
29 | */ | ||
30 | |||
31 | #include <unistd.h> | ||
32 | #include <sys/ioctl.h> | ||
33 | #ifdef MTRR_SUPPORT | ||
34 | #include <asm/mtrr.h> | ||
35 | #include <sys/fcntl.h> | ||
36 | #endif | ||
37 | |||
38 | #include "SDL_endian.h" | ||
39 | #include "SDL_timer.h" | ||
40 | #include "SDL_thread.h" | ||
41 | #include "SDL_video.h" | ||
42 | #include "SDL_mouse.h" | ||
43 | #include "../SDL_sysvideo.h" | ||
44 | #include "../SDL_pixels_c.h" | ||
45 | #include "../../events/SDL_events_c.h" | ||
46 | #include "SDL_x11video.h" | ||
47 | #include "SDL_x11wm_c.h" | ||
48 | #include "SDL_x11mouse_c.h" | ||
49 | #include "SDL_x11events_c.h" | ||
50 | #include "SDL_x11modes_c.h" | ||
51 | #include "SDL_x11image_c.h" | ||
52 | #include "SDL_x11yuv_c.h" | ||
53 | #include "SDL_x11gl_c.h" | ||
54 | #include "SDL_x11gamma_c.h" | ||
55 | #include "../blank_cursor.h" | ||
56 | |||
57 | #ifdef X_HAVE_UTF8_STRING | ||
58 | #include <locale.h> | ||
59 | #endif | ||
60 | |||
61 | /* Initialization/Query functions */ | ||
62 | static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat); | ||
63 | static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | ||
64 | static int X11_ToggleFullScreen(_THIS, int on); | ||
65 | static void X11_UpdateMouse(_THIS); | ||
66 | static int X11_SetColors(_THIS, int firstcolor, int ncolors, | ||
67 | SDL_Color *colors); | ||
68 | static int X11_SetGammaRamp(_THIS, Uint16 *ramp); | ||
69 | static void X11_VideoQuit(_THIS); | ||
70 | |||
71 | |||
72 | /* X11 driver bootstrap functions */ | ||
73 | |||
74 | static int X11_Available(void) | ||
75 | { | ||
76 | Display *display = NULL; | ||
77 | if ( SDL_X11_LoadSymbols() ) { | ||
78 | display = XOpenDisplay(NULL); | ||
79 | if ( display != NULL ) { | ||
80 | XCloseDisplay(display); | ||
81 | } | ||
82 | SDL_X11_UnloadSymbols(); | ||
83 | } | ||
84 | return(display != NULL); | ||
85 | } | ||
86 | |||
87 | static void X11_DeleteDevice(SDL_VideoDevice *device) | ||
88 | { | ||
89 | if ( device ) { | ||
90 | if ( device->hidden ) { | ||
91 | SDL_free(device->hidden); | ||
92 | } | ||
93 | if ( device->gl_data ) { | ||
94 | SDL_free(device->gl_data); | ||
95 | } | ||
96 | SDL_free(device); | ||
97 | SDL_X11_UnloadSymbols(); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | static SDL_VideoDevice *X11_CreateDevice(int devindex) | ||
102 | { | ||
103 | SDL_VideoDevice *device = NULL; | ||
104 | |||
105 | if ( SDL_X11_LoadSymbols() ) { | ||
106 | /* Initialize all variables that we clean on shutdown */ | ||
107 | device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); | ||
108 | if ( device ) { | ||
109 | SDL_memset(device, 0, (sizeof *device)); | ||
110 | device->hidden = (struct SDL_PrivateVideoData *) | ||
111 | SDL_malloc((sizeof *device->hidden)); | ||
112 | device->gl_data = (struct SDL_PrivateGLData *) | ||
113 | SDL_malloc((sizeof *device->gl_data)); | ||
114 | } | ||
115 | if ( (device == NULL) || (device->hidden == NULL) || | ||
116 | (device->gl_data == NULL) ) { | ||
117 | SDL_OutOfMemory(); | ||
118 | X11_DeleteDevice(device); /* calls SDL_X11_UnloadSymbols(). */ | ||
119 | return(0); | ||
120 | } | ||
121 | SDL_memset(device->hidden, 0, (sizeof *device->hidden)); | ||
122 | SDL_memset(device->gl_data, 0, (sizeof *device->gl_data)); | ||
123 | |||
124 | #if SDL_VIDEO_OPENGL_GLX | ||
125 | device->gl_data->swap_interval = -1; | ||
126 | #endif | ||
127 | |||
128 | /* Set the driver flags */ | ||
129 | device->handles_any_size = 1; | ||
130 | |||
131 | /* Set the function pointers */ | ||
132 | device->VideoInit = X11_VideoInit; | ||
133 | device->ListModes = X11_ListModes; | ||
134 | device->SetVideoMode = X11_SetVideoMode; | ||
135 | device->ToggleFullScreen = X11_ToggleFullScreen; | ||
136 | device->UpdateMouse = X11_UpdateMouse; | ||
137 | #if SDL_VIDEO_DRIVER_X11_XV | ||
138 | device->CreateYUVOverlay = X11_CreateYUVOverlay; | ||
139 | #endif | ||
140 | device->SetColors = X11_SetColors; | ||
141 | device->UpdateRects = NULL; | ||
142 | device->VideoQuit = X11_VideoQuit; | ||
143 | device->AllocHWSurface = X11_AllocHWSurface; | ||
144 | device->CheckHWBlit = NULL; | ||
145 | device->FillHWRect = NULL; | ||
146 | device->SetHWColorKey = NULL; | ||
147 | device->SetHWAlpha = NULL; | ||
148 | device->LockHWSurface = X11_LockHWSurface; | ||
149 | device->UnlockHWSurface = X11_UnlockHWSurface; | ||
150 | device->FlipHWSurface = X11_FlipHWSurface; | ||
151 | device->FreeHWSurface = X11_FreeHWSurface; | ||
152 | device->SetGamma = X11_SetVidModeGamma; | ||
153 | device->GetGamma = X11_GetVidModeGamma; | ||
154 | device->SetGammaRamp = X11_SetGammaRamp; | ||
155 | device->GetGammaRamp = NULL; | ||
156 | #if SDL_VIDEO_OPENGL_GLX | ||
157 | device->GL_LoadLibrary = X11_GL_LoadLibrary; | ||
158 | device->GL_GetProcAddress = X11_GL_GetProcAddress; | ||
159 | device->GL_GetAttribute = X11_GL_GetAttribute; | ||
160 | device->GL_MakeCurrent = X11_GL_MakeCurrent; | ||
161 | device->GL_SwapBuffers = X11_GL_SwapBuffers; | ||
162 | #endif | ||
163 | device->SetCaption = X11_SetCaption; | ||
164 | device->SetIcon = X11_SetIcon; | ||
165 | device->IconifyWindow = X11_IconifyWindow; | ||
166 | device->GrabInput = X11_GrabInput; | ||
167 | device->GetWMInfo = X11_GetWMInfo; | ||
168 | device->FreeWMCursor = X11_FreeWMCursor; | ||
169 | device->CreateWMCursor = X11_CreateWMCursor; | ||
170 | device->ShowWMCursor = X11_ShowWMCursor; | ||
171 | device->WarpWMCursor = X11_WarpWMCursor; | ||
172 | device->CheckMouseMode = X11_CheckMouseMode; | ||
173 | device->InitOSKeymap = X11_InitOSKeymap; | ||
174 | device->PumpEvents = X11_PumpEvents; | ||
175 | |||
176 | device->free = X11_DeleteDevice; | ||
177 | } | ||
178 | |||
179 | return device; | ||
180 | } | ||
181 | |||
182 | VideoBootStrap X11_bootstrap = { | ||
183 | "x11", "X Window System", | ||
184 | X11_Available, X11_CreateDevice | ||
185 | }; | ||
186 | |||
187 | /* Normal X11 error handler routine */ | ||
188 | static int (*X_handler)(Display *, XErrorEvent *) = NULL; | ||
189 | static int x_errhandler(Display *d, XErrorEvent *e) | ||
190 | { | ||
191 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
192 | extern int vm_error; | ||
193 | #endif | ||
194 | #if SDL_VIDEO_DRIVER_X11_DGAMOUSE | ||
195 | extern int dga_error; | ||
196 | #endif | ||
197 | |||
198 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
199 | /* VidMode errors are non-fatal. :) */ | ||
200 | /* Are the errors offset by one from the error base? | ||
201 | e.g. the error base is 143, the code is 148, and the | ||
202 | actual error is XF86VidModeExtensionDisabled (4) ? | ||
203 | */ | ||
204 | if ( (vm_error >= 0) && | ||
205 | (((e->error_code == BadRequest)&&(e->request_code == vm_error)) || | ||
206 | ((e->error_code > vm_error) && | ||
207 | (e->error_code <= (vm_error+XF86VidModeNumberErrors)))) ) { | ||
208 | #ifdef X11_DEBUG | ||
209 | { char errmsg[1024]; | ||
210 | XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg)); | ||
211 | printf("VidMode error: %s\n", errmsg); | ||
212 | } | ||
213 | #endif | ||
214 | return(0); | ||
215 | } | ||
216 | #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | ||
217 | |||
218 | #if SDL_VIDEO_DRIVER_X11_DGAMOUSE | ||
219 | /* DGA errors can be non-fatal. :) */ | ||
220 | if ( (dga_error >= 0) && | ||
221 | ((e->error_code > dga_error) && | ||
222 | (e->error_code <= (dga_error+XF86DGANumberErrors))) ) { | ||
223 | #ifdef X11_DEBUG | ||
224 | { char errmsg[1024]; | ||
225 | XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg)); | ||
226 | printf("DGA error: %s\n", errmsg); | ||
227 | } | ||
228 | #endif | ||
229 | return(0); | ||
230 | } | ||
231 | #endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */ | ||
232 | |||
233 | return(X_handler(d,e)); | ||
234 | } | ||
235 | |||
236 | /* X11 I/O error handler routine */ | ||
237 | static int (*XIO_handler)(Display *) = NULL; | ||
238 | static int xio_errhandler(Display *d) | ||
239 | { | ||
240 | /* Ack! Lost X11 connection! */ | ||
241 | |||
242 | /* We will crash if we try to clean up our display */ | ||
243 | if ( SDL_VideoSurface && current_video->hidden->Ximage ) { | ||
244 | SDL_VideoSurface->pixels = NULL; | ||
245 | } | ||
246 | current_video->hidden->X11_Display = NULL; | ||
247 | |||
248 | /* Continue with the standard X11 error handler */ | ||
249 | return(XIO_handler(d)); | ||
250 | } | ||
251 | |||
252 | static int (*Xext_handler)(Display *, _Xconst char *, _Xconst char *) = NULL; | ||
253 | static int xext_errhandler(Display *d, _Xconst char *ext, _Xconst char *reason) | ||
254 | { | ||
255 | #ifdef X11_DEBUG | ||
256 | printf("Xext error inside SDL (may be harmless):\n"); | ||
257 | printf(" Extension \"%s\" %s on display \"%s\".\n", | ||
258 | ext, reason, XDisplayString(d)); | ||
259 | #endif | ||
260 | |||
261 | if (SDL_strcmp(reason, "missing") == 0) { | ||
262 | /* | ||
263 | * Since the query itself, elsewhere, can handle a missing extension | ||
264 | * and the default behaviour in Xlib is to write to stderr, which | ||
265 | * generates unnecessary bug reports, we just ignore these. | ||
266 | */ | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | /* Everything else goes to the default handler... */ | ||
271 | return Xext_handler(d, ext, reason); | ||
272 | } | ||
273 | |||
274 | /* Find out what class name we should use */ | ||
275 | static char *get_classname(char *classname, int maxlen) | ||
276 | { | ||
277 | char *spot; | ||
278 | #if defined(__LINUX__) || defined(__FREEBSD__) | ||
279 | char procfile[1024]; | ||
280 | char linkfile[1024]; | ||
281 | int linksize; | ||
282 | #endif | ||
283 | |||
284 | /* First allow environment variable override */ | ||
285 | spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS"); | ||
286 | if ( spot ) { | ||
287 | SDL_strlcpy(classname, spot, maxlen); | ||
288 | return classname; | ||
289 | } | ||
290 | |||
291 | /* Next look at the application's executable name */ | ||
292 | #if defined(__LINUX__) || defined(__FREEBSD__) | ||
293 | #if defined(__LINUX__) | ||
294 | SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid()); | ||
295 | #elif defined(__FREEBSD__) | ||
296 | SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", getpid()); | ||
297 | #else | ||
298 | #error Where can we find the executable name? | ||
299 | #endif | ||
300 | linksize = readlink(procfile, linkfile, sizeof(linkfile)-1); | ||
301 | if ( linksize > 0 ) { | ||
302 | linkfile[linksize] = '\0'; | ||
303 | spot = SDL_strrchr(linkfile, '/'); | ||
304 | if ( spot ) { | ||
305 | SDL_strlcpy(classname, spot+1, maxlen); | ||
306 | } else { | ||
307 | SDL_strlcpy(classname, linkfile, maxlen); | ||
308 | } | ||
309 | return classname; | ||
310 | } | ||
311 | #endif /* __LINUX__ */ | ||
312 | |||
313 | /* Finally use the default we've used forever */ | ||
314 | SDL_strlcpy(classname, "SDL_App", maxlen); | ||
315 | return classname; | ||
316 | } | ||
317 | |||
318 | /* Create auxiliary (toplevel) windows with the current visual */ | ||
319 | static void create_aux_windows(_THIS) | ||
320 | { | ||
321 | int x = 0, y = 0; | ||
322 | char classname[1024]; | ||
323 | XSetWindowAttributes xattr; | ||
324 | XWMHints *hints; | ||
325 | unsigned long app_event_mask; | ||
326 | int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen)); | ||
327 | |||
328 | /* Look up some useful Atoms */ | ||
329 | WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False); | ||
330 | |||
331 | /* Don't create any extra windows if we are being managed */ | ||
332 | if ( SDL_windowid ) { | ||
333 | FSwindow = 0; | ||
334 | WMwindow = SDL_strtol(SDL_windowid, NULL, 0); | ||
335 | return; | ||
336 | } | ||
337 | |||
338 | if(FSwindow) | ||
339 | XDestroyWindow(SDL_Display, FSwindow); | ||
340 | |||
341 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
342 | if ( use_xinerama ) { | ||
343 | x = xinerama_info.x_org; | ||
344 | y = xinerama_info.y_org; | ||
345 | } | ||
346 | #endif | ||
347 | xattr.override_redirect = True; | ||
348 | xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0; | ||
349 | xattr.border_pixel = 0; | ||
350 | xattr.colormap = SDL_XColorMap; | ||
351 | |||
352 | FSwindow = XCreateWindow(SDL_Display, SDL_Root, | ||
353 | x, y, 32, 32, 0, | ||
354 | this->hidden->depth, InputOutput, SDL_Visual, | ||
355 | CWOverrideRedirect | CWBackPixel | CWBorderPixel | ||
356 | | CWColormap, | ||
357 | &xattr); | ||
358 | |||
359 | XSelectInput(SDL_Display, FSwindow, StructureNotifyMask); | ||
360 | |||
361 | /* Tell KDE to keep the fullscreen window on top */ | ||
362 | { | ||
363 | XEvent ev; | ||
364 | long mask; | ||
365 | |||
366 | SDL_memset(&ev, 0, sizeof(ev)); | ||
367 | ev.xclient.type = ClientMessage; | ||
368 | ev.xclient.window = SDL_Root; | ||
369 | ev.xclient.message_type = XInternAtom(SDL_Display, | ||
370 | "KWM_KEEP_ON_TOP", False); | ||
371 | ev.xclient.format = 32; | ||
372 | ev.xclient.data.l[0] = FSwindow; | ||
373 | ev.xclient.data.l[1] = CurrentTime; | ||
374 | mask = SubstructureRedirectMask; | ||
375 | XSendEvent(SDL_Display, SDL_Root, False, mask, &ev); | ||
376 | } | ||
377 | |||
378 | hints = NULL; | ||
379 | if(WMwindow) { | ||
380 | /* All window attributes must survive the recreation */ | ||
381 | hints = XGetWMHints(SDL_Display, WMwindow); | ||
382 | XDestroyWindow(SDL_Display, WMwindow); | ||
383 | } | ||
384 | |||
385 | /* Create the window for windowed management */ | ||
386 | /* (reusing the xattr structure above) */ | ||
387 | WMwindow = XCreateWindow(SDL_Display, SDL_Root, | ||
388 | x, y, 32, 32, 0, | ||
389 | this->hidden->depth, InputOutput, SDL_Visual, | ||
390 | CWBackPixel | CWBorderPixel | CWColormap, | ||
391 | &xattr); | ||
392 | |||
393 | /* Set the input hints so we get keyboard input */ | ||
394 | if(!hints) { | ||
395 | hints = XAllocWMHints(); | ||
396 | hints->input = True; | ||
397 | hints->flags = InputHint; | ||
398 | } | ||
399 | XSetWMHints(SDL_Display, WMwindow, hints); | ||
400 | XFree(hints); | ||
401 | X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon); | ||
402 | |||
403 | app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ||
404 | | PropertyChangeMask | StructureNotifyMask | KeymapStateMask; | ||
405 | XSelectInput(SDL_Display, WMwindow, app_event_mask); | ||
406 | |||
407 | /* Set the class hints so we can get an icon (AfterStep) */ | ||
408 | get_classname(classname, sizeof(classname)); | ||
409 | { | ||
410 | XClassHint *classhints; | ||
411 | classhints = XAllocClassHint(); | ||
412 | if(classhints != NULL) { | ||
413 | classhints->res_name = classname; | ||
414 | classhints->res_class = classname; | ||
415 | XSetClassHint(SDL_Display, WMwindow, classhints); | ||
416 | XFree(classhints); | ||
417 | } | ||
418 | } | ||
419 | |||
420 | { | ||
421 | pid_t pid = getpid(); | ||
422 | char hostname[256]; | ||
423 | |||
424 | if (pid > 0 && gethostname(hostname, sizeof(hostname)) > -1) { | ||
425 | Atom _NET_WM_PID = XInternAtom(SDL_Display, "_NET_WM_PID", False); | ||
426 | Atom WM_CLIENT_MACHINE = XInternAtom(SDL_Display, "WM_CLIENT_MACHINE", False); | ||
427 | |||
428 | hostname[sizeof(hostname)-1] = '\0'; | ||
429 | XChangeProperty(SDL_Display, WMwindow, _NET_WM_PID, XA_CARDINAL, 32, | ||
430 | PropModeReplace, (unsigned char *)&pid, 1); | ||
431 | XChangeProperty(SDL_Display, WMwindow, WM_CLIENT_MACHINE, XA_STRING, 8, | ||
432 | PropModeReplace, (unsigned char *)hostname, SDL_strlen(hostname)); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | /* Setup the communication with the IM server */ | ||
437 | /* create_aux_windows may be called several times against the same | ||
438 | Display. We should reuse the SDL_IM if one has been opened for | ||
439 | the Display, so we should not simply reset SDL_IM here. */ | ||
440 | |||
441 | #ifdef X_HAVE_UTF8_STRING | ||
442 | if (SDL_X11_HAVE_UTF8) { | ||
443 | /* Discard obsolete resources if any. */ | ||
444 | if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) { | ||
445 | /* Just a double check. I don't think this | ||
446 | code is ever executed. */ | ||
447 | SDL_SetError("display has changed while an IM is kept"); | ||
448 | if (SDL_IC) { | ||
449 | XUnsetICFocus(SDL_IC); | ||
450 | XDestroyIC(SDL_IC); | ||
451 | SDL_IC = NULL; | ||
452 | } | ||
453 | XCloseIM(SDL_IM); | ||
454 | SDL_IM = NULL; | ||
455 | } | ||
456 | |||
457 | /* Open an input method. */ | ||
458 | if (SDL_IM == NULL) { | ||
459 | char *old_locale = NULL, *old_modifiers = NULL; | ||
460 | const char *p; | ||
461 | size_t n; | ||
462 | /* I'm not comfortable to do locale setup | ||
463 | here. However, we need C library locale | ||
464 | (and xlib modifiers) to be set based on the | ||
465 | user's preference to use XIM, and many | ||
466 | existing game programs doesn't take care of | ||
467 | users' locale preferences, so someone other | ||
468 | than the game program should do it. | ||
469 | Moreover, ones say that some game programs | ||
470 | heavily rely on the C locale behaviour, | ||
471 | e.g., strcol()'s, and we can't change the C | ||
472 | library locale. Given the situation, I | ||
473 | couldn't find better place to do the | ||
474 | job... */ | ||
475 | |||
476 | /* Save the current (application program's) | ||
477 | locale settings. */ | ||
478 | p = setlocale(LC_ALL, NULL); | ||
479 | if ( p ) { | ||
480 | n = SDL_strlen(p)+1; | ||
481 | old_locale = SDL_stack_alloc(char, n); | ||
482 | if ( old_locale ) { | ||
483 | SDL_strlcpy(old_locale, p, n); | ||
484 | } | ||
485 | } | ||
486 | p = XSetLocaleModifiers(NULL); | ||
487 | if ( p ) { | ||
488 | n = SDL_strlen(p)+1; | ||
489 | old_modifiers = SDL_stack_alloc(char, n); | ||
490 | if ( old_modifiers ) { | ||
491 | SDL_strlcpy(old_modifiers, p, n); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | /* Fetch the user's preferences and open the | ||
496 | input method with them. */ | ||
497 | setlocale(LC_ALL, ""); | ||
498 | XSetLocaleModifiers(""); | ||
499 | SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname); | ||
500 | |||
501 | /* Restore the application's locale settings | ||
502 | so that we don't break the application's | ||
503 | expected behaviour. */ | ||
504 | if ( old_locale ) { | ||
505 | /* We need to restore the C library | ||
506 | locale first, since the | ||
507 | interpretation of the X modifier | ||
508 | may depend on it. */ | ||
509 | setlocale(LC_ALL, old_locale); | ||
510 | SDL_stack_free(old_locale); | ||
511 | } | ||
512 | if ( old_modifiers ) { | ||
513 | XSetLocaleModifiers(old_modifiers); | ||
514 | SDL_stack_free(old_modifiers); | ||
515 | } | ||
516 | } | ||
517 | |||
518 | /* Create a new input context for the new window just created. */ | ||
519 | if (SDL_IM == NULL) { | ||
520 | SDL_SetError("no input method could be opened"); | ||
521 | } else { | ||
522 | if (SDL_IC != NULL) { | ||
523 | /* Discard the old IC before creating new one. */ | ||
524 | XUnsetICFocus(SDL_IC); | ||
525 | XDestroyIC(SDL_IC); | ||
526 | } | ||
527 | /* Theoretically we should check the current IM supports | ||
528 | PreeditNothing+StatusNothing style (i.e., root window method) | ||
529 | before creating the IC. However, it is the bottom line method, | ||
530 | and we supports any other options. If the IM didn't support | ||
531 | root window method, the following call fails, and SDL falls | ||
532 | back to pre-XIM keyboard handling. */ | ||
533 | SDL_IC = pXCreateIC(SDL_IM, | ||
534 | XNClientWindow, WMwindow, | ||
535 | XNFocusWindow, WMwindow, | ||
536 | XNInputStyle, XIMPreeditNothing | XIMStatusNothing, | ||
537 | XNResourceName, classname, | ||
538 | XNResourceClass, classname, | ||
539 | NULL); | ||
540 | |||
541 | if (SDL_IC == NULL) { | ||
542 | SDL_SetError("no input context could be created"); | ||
543 | XCloseIM(SDL_IM); | ||
544 | SDL_IM = NULL; | ||
545 | } else { | ||
546 | /* We need to receive X events that an IM wants and to pass | ||
547 | them to the IM through XFilterEvent. The set of events may | ||
548 | vary depending on the IM implementation and the options | ||
549 | specified through various routes. Although unlikely, the | ||
550 | xlib specification allows IM to change the event requirement | ||
551 | with its own circumstances, it is safe to call SelectInput | ||
552 | whenever we re-create an IC. */ | ||
553 | unsigned long mask = 0; | ||
554 | char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL); | ||
555 | if (ret != NULL) { | ||
556 | XUnsetICFocus(SDL_IC); | ||
557 | XDestroyIC(SDL_IC); | ||
558 | SDL_IC = NULL; | ||
559 | SDL_SetError("no input context could be created"); | ||
560 | XCloseIM(SDL_IM); | ||
561 | SDL_IM = NULL; | ||
562 | } else { | ||
563 | XSelectInput(SDL_Display, WMwindow, app_event_mask | mask); | ||
564 | XSetICFocus(SDL_IC); | ||
565 | } | ||
566 | } | ||
567 | } | ||
568 | } | ||
569 | #endif | ||
570 | |||
571 | /* Allow the window to be deleted by the window manager */ | ||
572 | XSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1); | ||
573 | } | ||
574 | |||
575 | static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) | ||
576 | { | ||
577 | const char *env; | ||
578 | char *display; | ||
579 | int i; | ||
580 | |||
581 | /* Open the X11 display */ | ||
582 | display = NULL; /* Get it from DISPLAY environment variable */ | ||
583 | |||
584 | if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) || | ||
585 | (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) { | ||
586 | local_X11 = 1; | ||
587 | } else { | ||
588 | local_X11 = 0; | ||
589 | } | ||
590 | SDL_Display = XOpenDisplay(display); | ||
591 | #if defined(__osf__) && defined(SDL_VIDEO_DRIVER_X11_DYNAMIC) | ||
592 | /* On Tru64 if linking without -lX11, it fails and you get following message. | ||
593 | * Xlib: connection to ":0.0" refused by server | ||
594 | * Xlib: XDM authorization key matches an existing client! | ||
595 | * | ||
596 | * It succeeds if retrying 1 second later | ||
597 | * or if running xhost +localhost on shell. | ||
598 | * | ||
599 | */ | ||
600 | if ( SDL_Display == NULL ) { | ||
601 | SDL_Delay(1000); | ||
602 | SDL_Display = XOpenDisplay(display); | ||
603 | } | ||
604 | #endif | ||
605 | if ( SDL_Display == NULL ) { | ||
606 | SDL_SetError("Couldn't open X11 display"); | ||
607 | return(-1); | ||
608 | } | ||
609 | #ifdef X11_DEBUG | ||
610 | XSynchronize(SDL_Display, True); | ||
611 | #endif | ||
612 | |||
613 | /* Create an alternate X display for graphics updates -- allows us | ||
614 | to do graphics updates in a separate thread from event handling. | ||
615 | Thread-safe X11 doesn't seem to exist. | ||
616 | */ | ||
617 | GFX_Display = XOpenDisplay(display); | ||
618 | if ( GFX_Display == NULL ) { | ||
619 | XCloseDisplay(SDL_Display); | ||
620 | SDL_Display = NULL; | ||
621 | SDL_SetError("Couldn't open X11 display"); | ||
622 | return(-1); | ||
623 | } | ||
624 | |||
625 | /* Set the normal X error handler */ | ||
626 | X_handler = XSetErrorHandler(x_errhandler); | ||
627 | |||
628 | /* Set the error handler if we lose the X display */ | ||
629 | XIO_handler = XSetIOErrorHandler(xio_errhandler); | ||
630 | |||
631 | /* Set the X extension error handler */ | ||
632 | Xext_handler = XSetExtensionErrorHandler(xext_errhandler); | ||
633 | |||
634 | /* use default screen (from $DISPLAY) */ | ||
635 | SDL_Screen = DefaultScreen(SDL_Display); | ||
636 | |||
637 | #ifndef NO_SHARED_MEMORY | ||
638 | /* Check for MIT shared memory extension */ | ||
639 | use_mitshm = 0; | ||
640 | if ( local_X11 ) { | ||
641 | use_mitshm = XShmQueryExtension(SDL_Display); | ||
642 | } | ||
643 | #endif /* NO_SHARED_MEMORY */ | ||
644 | |||
645 | /* Get the available video modes */ | ||
646 | if(X11_GetVideoModes(this) < 0) { | ||
647 | XCloseDisplay(GFX_Display); | ||
648 | GFX_Display = NULL; | ||
649 | XCloseDisplay(SDL_Display); | ||
650 | SDL_Display = NULL; | ||
651 | return -1; | ||
652 | } | ||
653 | |||
654 | /* Determine the current screen size */ | ||
655 | this->info.current_w = DisplayWidth(SDL_Display, SDL_Screen); | ||
656 | this->info.current_h = DisplayHeight(SDL_Display, SDL_Screen); | ||
657 | |||
658 | /* Determine the default screen depth: | ||
659 | Use the default visual (or at least one with the same depth) */ | ||
660 | SDL_DisplayColormap = DefaultColormap(SDL_Display, SDL_Screen); | ||
661 | for(i = 0; i < this->hidden->nvisuals; i++) | ||
662 | if(this->hidden->visuals[i].depth == DefaultDepth(SDL_Display, | ||
663 | SDL_Screen)) | ||
664 | break; | ||
665 | if(i == this->hidden->nvisuals) { | ||
666 | /* default visual was useless, take the deepest one instead */ | ||
667 | i = 0; | ||
668 | } | ||
669 | SDL_Visual = this->hidden->visuals[i].visual; | ||
670 | if ( SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen) ) { | ||
671 | SDL_XColorMap = SDL_DisplayColormap; | ||
672 | } else { | ||
673 | SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, | ||
674 | SDL_Visual, AllocNone); | ||
675 | } | ||
676 | this->hidden->depth = this->hidden->visuals[i].depth; | ||
677 | vformat->BitsPerPixel = this->hidden->visuals[i].bpp; | ||
678 | if ( vformat->BitsPerPixel > 8 ) { | ||
679 | vformat->Rmask = SDL_Visual->red_mask; | ||
680 | vformat->Gmask = SDL_Visual->green_mask; | ||
681 | vformat->Bmask = SDL_Visual->blue_mask; | ||
682 | } | ||
683 | if ( this->hidden->depth == 32 ) { | ||
684 | vformat->Amask = (0xFFFFFFFF & ~(vformat->Rmask|vformat->Gmask|vformat->Bmask)); | ||
685 | } | ||
686 | X11_SaveVidModeGamma(this); | ||
687 | |||
688 | /* Allow environment override of screensaver disable. */ | ||
689 | env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); | ||
690 | if ( env ) { | ||
691 | allow_screensaver = SDL_atoi(env); | ||
692 | } else { | ||
693 | #ifdef SDL_VIDEO_DISABLE_SCREENSAVER | ||
694 | allow_screensaver = 0; | ||
695 | #else | ||
696 | allow_screensaver = 1; | ||
697 | #endif | ||
698 | } | ||
699 | |||
700 | /* See if we have been passed a window to use */ | ||
701 | SDL_windowid = SDL_getenv("SDL_WINDOWID"); | ||
702 | |||
703 | /* Create the fullscreen and managed windows */ | ||
704 | create_aux_windows(this); | ||
705 | |||
706 | /* Create the blank cursor */ | ||
707 | SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, | ||
708 | BLANK_CWIDTH, BLANK_CHEIGHT, | ||
709 | BLANK_CHOTX, BLANK_CHOTY); | ||
710 | |||
711 | /* Fill in some window manager capabilities */ | ||
712 | this->info.wm_available = 1; | ||
713 | |||
714 | /* We're done! */ | ||
715 | XFlush(SDL_Display); | ||
716 | return(0); | ||
717 | } | ||
718 | |||
719 | static void X11_DestroyWindow(_THIS, SDL_Surface *screen) | ||
720 | { | ||
721 | /* Clean up OpenGL */ | ||
722 | if ( screen ) { | ||
723 | screen->flags &= ~(SDL_OPENGL|SDL_OPENGLBLIT); | ||
724 | } | ||
725 | X11_GL_Shutdown(this); | ||
726 | |||
727 | if ( ! SDL_windowid ) { | ||
728 | /* Hide the managed window */ | ||
729 | if ( WMwindow ) { | ||
730 | XUnmapWindow(SDL_Display, WMwindow); | ||
731 | } | ||
732 | if ( screen && (screen->flags & SDL_FULLSCREEN) ) { | ||
733 | screen->flags &= ~SDL_FULLSCREEN; | ||
734 | X11_LeaveFullScreen(this); | ||
735 | } | ||
736 | |||
737 | /* Destroy the output window */ | ||
738 | if ( SDL_Window ) { | ||
739 | XDestroyWindow(SDL_Display, SDL_Window); | ||
740 | } | ||
741 | |||
742 | /* Free the colormap entries */ | ||
743 | if ( SDL_XPixels ) { | ||
744 | int numcolors; | ||
745 | unsigned long pixel; | ||
746 | numcolors = SDL_Visual->map_entries; | ||
747 | for ( pixel=0; pixel<numcolors; ++pixel ) { | ||
748 | while ( SDL_XPixels[pixel] > 0 ) { | ||
749 | XFreeColors(GFX_Display, | ||
750 | SDL_DisplayColormap,&pixel,1,0); | ||
751 | --SDL_XPixels[pixel]; | ||
752 | } | ||
753 | } | ||
754 | SDL_free(SDL_XPixels); | ||
755 | SDL_XPixels = NULL; | ||
756 | } | ||
757 | |||
758 | /* Free the graphics context */ | ||
759 | if ( SDL_GC ) { | ||
760 | XFreeGC(SDL_Display, SDL_GC); | ||
761 | SDL_GC = 0; | ||
762 | } | ||
763 | } | ||
764 | } | ||
765 | |||
766 | static SDL_bool X11_WindowPosition(_THIS, int *x, int *y, int w, int h) | ||
767 | { | ||
768 | const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); | ||
769 | const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); | ||
770 | if ( window ) { | ||
771 | if ( SDL_sscanf(window, "%d,%d", x, y) == 2 ) { | ||
772 | return SDL_TRUE; | ||
773 | } | ||
774 | if ( SDL_strcmp(window, "center") == 0 ) { | ||
775 | center = window; | ||
776 | } | ||
777 | } | ||
778 | if ( center ) { | ||
779 | *x = (DisplayWidth(SDL_Display, SDL_Screen) - w)/2; | ||
780 | *y = (DisplayHeight(SDL_Display, SDL_Screen) - h)/2; | ||
781 | return SDL_TRUE; | ||
782 | } | ||
783 | return SDL_FALSE; | ||
784 | } | ||
785 | |||
786 | static void X11_SetSizeHints(_THIS, int w, int h, Uint32 flags) | ||
787 | { | ||
788 | XSizeHints *hints; | ||
789 | |||
790 | hints = XAllocSizeHints(); | ||
791 | if ( hints ) { | ||
792 | if (!(flags & SDL_RESIZABLE)) { | ||
793 | hints->min_width = hints->max_width = w; | ||
794 | hints->min_height = hints->max_height = h; | ||
795 | hints->flags = PMaxSize | PMinSize; | ||
796 | } | ||
797 | if ( flags & SDL_FULLSCREEN ) { | ||
798 | hints->x = 0; | ||
799 | hints->y = 0; | ||
800 | hints->flags |= USPosition; | ||
801 | } else | ||
802 | /* Center it, if desired */ | ||
803 | if ( X11_WindowPosition(this, &hints->x, &hints->y, w, h) ) { | ||
804 | hints->flags |= USPosition; | ||
805 | |||
806 | /* Hints must be set before moving the window, otherwise an | ||
807 | unwanted ConfigureNotify event will be issued */ | ||
808 | XSetWMNormalHints(SDL_Display, WMwindow, hints); | ||
809 | |||
810 | XMoveWindow(SDL_Display, WMwindow, hints->x, hints->y); | ||
811 | |||
812 | /* Flush the resize event so we don't catch it later */ | ||
813 | XSync(SDL_Display, True); | ||
814 | } | ||
815 | XSetWMNormalHints(SDL_Display, WMwindow, hints); | ||
816 | XFree(hints); | ||
817 | } | ||
818 | |||
819 | /* Respect the window caption style */ | ||
820 | if ( flags & SDL_NOFRAME ) { | ||
821 | SDL_bool set; | ||
822 | Atom WM_HINTS; | ||
823 | |||
824 | /* We haven't modified the window manager hints yet */ | ||
825 | set = SDL_FALSE; | ||
826 | |||
827 | /* First try to set MWM hints */ | ||
828 | WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); | ||
829 | if ( WM_HINTS != None ) { | ||
830 | /* Hints used by Motif compliant window managers */ | ||
831 | struct { | ||
832 | unsigned long flags; | ||
833 | unsigned long functions; | ||
834 | unsigned long decorations; | ||
835 | long input_mode; | ||
836 | unsigned long status; | ||
837 | } MWMHints = { (1L << 1), 0, 0, 0, 0 }; | ||
838 | |||
839 | XChangeProperty(SDL_Display, WMwindow, | ||
840 | WM_HINTS, WM_HINTS, 32, | ||
841 | PropModeReplace, | ||
842 | (unsigned char *)&MWMHints, | ||
843 | sizeof(MWMHints)/sizeof(long)); | ||
844 | set = SDL_TRUE; | ||
845 | } | ||
846 | /* Now try to set KWM hints */ | ||
847 | WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); | ||
848 | if ( WM_HINTS != None ) { | ||
849 | long KWMHints = 0; | ||
850 | |||
851 | XChangeProperty(SDL_Display, WMwindow, | ||
852 | WM_HINTS, WM_HINTS, 32, | ||
853 | PropModeReplace, | ||
854 | (unsigned char *)&KWMHints, | ||
855 | sizeof(KWMHints)/sizeof(long)); | ||
856 | set = SDL_TRUE; | ||
857 | } | ||
858 | /* Now try to set GNOME hints */ | ||
859 | WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); | ||
860 | if ( WM_HINTS != None ) { | ||
861 | long GNOMEHints = 0; | ||
862 | |||
863 | XChangeProperty(SDL_Display, WMwindow, | ||
864 | WM_HINTS, WM_HINTS, 32, | ||
865 | PropModeReplace, | ||
866 | (unsigned char *)&GNOMEHints, | ||
867 | sizeof(GNOMEHints)/sizeof(long)); | ||
868 | set = SDL_TRUE; | ||
869 | } | ||
870 | /* Finally set the transient hints if necessary */ | ||
871 | if ( ! set ) { | ||
872 | XSetTransientForHint(SDL_Display, WMwindow, SDL_Root); | ||
873 | } | ||
874 | } else { | ||
875 | SDL_bool set; | ||
876 | Atom WM_HINTS; | ||
877 | |||
878 | /* We haven't modified the window manager hints yet */ | ||
879 | set = SDL_FALSE; | ||
880 | |||
881 | /* First try to unset MWM hints */ | ||
882 | WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); | ||
883 | if ( WM_HINTS != None ) { | ||
884 | XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); | ||
885 | set = SDL_TRUE; | ||
886 | } | ||
887 | /* Now try to unset KWM hints */ | ||
888 | WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); | ||
889 | if ( WM_HINTS != None ) { | ||
890 | XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); | ||
891 | set = SDL_TRUE; | ||
892 | } | ||
893 | /* Now try to unset GNOME hints */ | ||
894 | WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); | ||
895 | if ( WM_HINTS != None ) { | ||
896 | XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); | ||
897 | set = SDL_TRUE; | ||
898 | } | ||
899 | /* Finally unset the transient hints if necessary */ | ||
900 | if ( ! set ) { | ||
901 | XDeleteProperty(SDL_Display, WMwindow, XA_WM_TRANSIENT_FOR); | ||
902 | } | ||
903 | } | ||
904 | } | ||
905 | |||
906 | static int X11_CreateWindow(_THIS, SDL_Surface *screen, | ||
907 | int w, int h, int bpp, Uint32 flags) | ||
908 | { | ||
909 | int i, depth; | ||
910 | Visual *vis; | ||
911 | int vis_change; | ||
912 | Uint32 Amask; | ||
913 | |||
914 | /* If a window is already present, destroy it and start fresh */ | ||
915 | if ( SDL_Window ) { | ||
916 | X11_DestroyWindow(this, screen); | ||
917 | switch_waiting = 0; /* Prevent jump back to now-meaningless state. */ | ||
918 | } | ||
919 | |||
920 | /* See if we have been given a window id */ | ||
921 | if ( SDL_windowid ) { | ||
922 | SDL_Window = SDL_strtol(SDL_windowid, NULL, 0); | ||
923 | } else { | ||
924 | SDL_Window = 0; | ||
925 | } | ||
926 | |||
927 | /* find out which visual we are going to use */ | ||
928 | if ( flags & SDL_OPENGL ) { | ||
929 | XVisualInfo *vi; | ||
930 | |||
931 | vi = X11_GL_GetVisual(this); | ||
932 | if( !vi ) { | ||
933 | return -1; | ||
934 | } | ||
935 | vis = vi->visual; | ||
936 | depth = vi->depth; | ||
937 | } else if ( SDL_windowid ) { | ||
938 | XWindowAttributes a; | ||
939 | |||
940 | XGetWindowAttributes(SDL_Display, SDL_Window, &a); | ||
941 | vis = a.visual; | ||
942 | depth = a.depth; | ||
943 | } else { | ||
944 | for ( i = 0; i < this->hidden->nvisuals; i++ ) { | ||
945 | if ( this->hidden->visuals[i].bpp == bpp ) | ||
946 | break; | ||
947 | } | ||
948 | if ( i == this->hidden->nvisuals ) { | ||
949 | SDL_SetError("No matching visual for requested depth"); | ||
950 | return -1; /* should never happen */ | ||
951 | } | ||
952 | vis = this->hidden->visuals[i].visual; | ||
953 | depth = this->hidden->visuals[i].depth; | ||
954 | } | ||
955 | #ifdef X11_DEBUG | ||
956 | printf("Choosing %s visual at %d bpp - %d colormap entries\n", vis->class == PseudoColor ? "PseudoColor" : (vis->class == TrueColor ? "TrueColor" : (vis->class == DirectColor ? "DirectColor" : "Unknown")), depth, vis->map_entries); | ||
957 | #endif | ||
958 | vis_change = (vis != SDL_Visual); | ||
959 | SDL_Visual = vis; | ||
960 | this->hidden->depth = depth; | ||
961 | |||
962 | /* Allocate the new pixel format for this video mode */ | ||
963 | if ( this->hidden->depth == 32 ) { | ||
964 | Amask = (0xFFFFFFFF & ~(vis->red_mask|vis->green_mask|vis->blue_mask)); | ||
965 | } else { | ||
966 | Amask = 0; | ||
967 | } | ||
968 | if ( ! SDL_ReallocFormat(screen, bpp, | ||
969 | vis->red_mask, vis->green_mask, vis->blue_mask, Amask) ) { | ||
970 | return -1; | ||
971 | } | ||
972 | |||
973 | /* Create the appropriate colormap */ | ||
974 | if ( SDL_XColorMap != SDL_DisplayColormap ) { | ||
975 | XFreeColormap(SDL_Display, SDL_XColorMap); | ||
976 | } | ||
977 | if ( SDL_Visual->class == PseudoColor ) { | ||
978 | int ncolors; | ||
979 | |||
980 | /* Allocate the pixel flags */ | ||
981 | ncolors = SDL_Visual->map_entries; | ||
982 | SDL_XPixels = SDL_malloc(ncolors * sizeof(int)); | ||
983 | if(SDL_XPixels == NULL) { | ||
984 | SDL_OutOfMemory(); | ||
985 | return -1; | ||
986 | } | ||
987 | SDL_memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels)); | ||
988 | |||
989 | /* always allocate a private colormap on non-default visuals */ | ||
990 | if ( SDL_Visual != DefaultVisual(SDL_Display, SDL_Screen) ) { | ||
991 | flags |= SDL_HWPALETTE; | ||
992 | } | ||
993 | if ( flags & SDL_HWPALETTE ) { | ||
994 | screen->flags |= SDL_HWPALETTE; | ||
995 | SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, | ||
996 | SDL_Visual, AllocAll); | ||
997 | } else { | ||
998 | SDL_XColorMap = SDL_DisplayColormap; | ||
999 | } | ||
1000 | } else if ( SDL_Visual->class == DirectColor ) { | ||
1001 | |||
1002 | /* Create a colormap which we can manipulate for gamma */ | ||
1003 | SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, | ||
1004 | SDL_Visual, AllocAll); | ||
1005 | XSync(SDL_Display, False); | ||
1006 | |||
1007 | /* Initialize the colormap to the identity mapping */ | ||
1008 | SDL_GetGammaRamp(0, 0, 0); | ||
1009 | this->screen = screen; | ||
1010 | X11_SetGammaRamp(this, this->gamma); | ||
1011 | this->screen = NULL; | ||
1012 | } else { | ||
1013 | /* Create a read-only colormap for our window */ | ||
1014 | SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, | ||
1015 | SDL_Visual, AllocNone); | ||
1016 | } | ||
1017 | |||
1018 | /* Recreate the auxiliary windows, if needed (required for GL) */ | ||
1019 | if ( vis_change ) | ||
1020 | create_aux_windows(this); | ||
1021 | |||
1022 | if(screen->flags & SDL_HWPALETTE) { | ||
1023 | /* Since the full-screen window might have got a nonzero background | ||
1024 | colour (0 is white on some displays), we should reset the | ||
1025 | background to 0 here since that is what the user expects | ||
1026 | with a private colormap */ | ||
1027 | XSetWindowBackground(SDL_Display, FSwindow, 0); | ||
1028 | XClearWindow(SDL_Display, FSwindow); | ||
1029 | } | ||
1030 | |||
1031 | /* resize the (possibly new) window manager window */ | ||
1032 | if( !SDL_windowid ) { | ||
1033 | X11_SetSizeHints(this, w, h, flags); | ||
1034 | window_w = w; | ||
1035 | window_h = h; | ||
1036 | XResizeWindow(SDL_Display, WMwindow, w, h); | ||
1037 | } | ||
1038 | |||
1039 | /* Create (or use) the X11 display window */ | ||
1040 | if ( !SDL_windowid ) { | ||
1041 | if ( flags & SDL_OPENGL ) { | ||
1042 | if ( X11_GL_CreateWindow(this, w, h) < 0 ) { | ||
1043 | return(-1); | ||
1044 | } | ||
1045 | } else { | ||
1046 | XSetWindowAttributes swa; | ||
1047 | |||
1048 | swa.background_pixel = 0; | ||
1049 | swa.border_pixel = 0; | ||
1050 | swa.colormap = SDL_XColorMap; | ||
1051 | SDL_Window = XCreateWindow(SDL_Display, WMwindow, | ||
1052 | 0, 0, w, h, 0, depth, | ||
1053 | InputOutput, SDL_Visual, | ||
1054 | CWBackPixel | CWBorderPixel | ||
1055 | | CWColormap, &swa); | ||
1056 | } | ||
1057 | /* Only manage our input if we own the window */ | ||
1058 | XSelectInput(SDL_Display, SDL_Window, | ||
1059 | ( EnterWindowMask | LeaveWindowMask | ||
1060 | | ButtonPressMask | ButtonReleaseMask | ||
1061 | | PointerMotionMask | ExposureMask )); | ||
1062 | } | ||
1063 | /* Create the graphics context here, once we have a window */ | ||
1064 | if ( flags & SDL_OPENGL ) { | ||
1065 | if ( X11_GL_CreateContext(this) < 0 ) { | ||
1066 | return(-1); | ||
1067 | } else { | ||
1068 | screen->flags |= SDL_OPENGL; | ||
1069 | } | ||
1070 | } else { | ||
1071 | XGCValues gcv; | ||
1072 | |||
1073 | gcv.graphics_exposures = False; | ||
1074 | SDL_GC = XCreateGC(SDL_Display, SDL_Window, | ||
1075 | GCGraphicsExposures, &gcv); | ||
1076 | if ( ! SDL_GC ) { | ||
1077 | SDL_SetError("Couldn't create graphics context"); | ||
1078 | return(-1); | ||
1079 | } | ||
1080 | } | ||
1081 | |||
1082 | /* Set our colormaps when not setting a GL mode */ | ||
1083 | if ( ! (flags & SDL_OPENGL) ) { | ||
1084 | XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap); | ||
1085 | if( !SDL_windowid ) { | ||
1086 | XSetWindowColormap(SDL_Display, FSwindow, SDL_XColorMap); | ||
1087 | XSetWindowColormap(SDL_Display, WMwindow, SDL_XColorMap); | ||
1088 | } | ||
1089 | } | ||
1090 | |||
1091 | #if 0 /* This is an experiment - are the graphics faster now? - nope. */ | ||
1092 | if ( SDL_getenv("SDL_VIDEO_X11_BACKINGSTORE") ) | ||
1093 | #endif | ||
1094 | /* Cache the window in the server, when possible */ | ||
1095 | { | ||
1096 | Screen *xscreen; | ||
1097 | XSetWindowAttributes a; | ||
1098 | |||
1099 | xscreen = ScreenOfDisplay(SDL_Display, SDL_Screen); | ||
1100 | a.backing_store = DoesBackingStore(xscreen); | ||
1101 | if ( a.backing_store != NotUseful ) { | ||
1102 | XChangeWindowAttributes(SDL_Display, SDL_Window, | ||
1103 | CWBackingStore, &a); | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | /* Map them both and go fullscreen, if requested */ | ||
1108 | if ( ! SDL_windowid ) { | ||
1109 | XMapWindow(SDL_Display, SDL_Window); | ||
1110 | XMapWindow(SDL_Display, WMwindow); | ||
1111 | X11_WaitMapped(this, WMwindow); | ||
1112 | if ( flags & SDL_FULLSCREEN ) { | ||
1113 | screen->flags |= SDL_FULLSCREEN; | ||
1114 | X11_EnterFullScreen(this); | ||
1115 | } else { | ||
1116 | screen->flags &= ~SDL_FULLSCREEN; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | return(0); | ||
1121 | } | ||
1122 | |||
1123 | static int X11_ResizeWindow(_THIS, | ||
1124 | SDL_Surface *screen, int w, int h, Uint32 flags) | ||
1125 | { | ||
1126 | if ( ! SDL_windowid ) { | ||
1127 | /* Resize the window manager window */ | ||
1128 | X11_SetSizeHints(this, w, h, flags); | ||
1129 | window_w = w; | ||
1130 | window_h = h; | ||
1131 | XResizeWindow(SDL_Display, WMwindow, w, h); | ||
1132 | |||
1133 | /* Resize the fullscreen and display windows */ | ||
1134 | if ( flags & SDL_FULLSCREEN ) { | ||
1135 | if ( screen->flags & SDL_FULLSCREEN ) { | ||
1136 | X11_ResizeFullScreen(this); | ||
1137 | } else { | ||
1138 | screen->flags |= SDL_FULLSCREEN; | ||
1139 | X11_EnterFullScreen(this); | ||
1140 | } | ||
1141 | } else { | ||
1142 | if ( screen->flags & SDL_FULLSCREEN ) { | ||
1143 | screen->flags &= ~SDL_FULLSCREEN; | ||
1144 | X11_LeaveFullScreen(this); | ||
1145 | } | ||
1146 | } | ||
1147 | XResizeWindow(SDL_Display, SDL_Window, w, h); | ||
1148 | } | ||
1149 | return(0); | ||
1150 | } | ||
1151 | |||
1152 | SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, | ||
1153 | int width, int height, int bpp, Uint32 flags) | ||
1154 | { | ||
1155 | Uint32 saved_flags; | ||
1156 | |||
1157 | /* Lock the event thread, in multi-threading environments */ | ||
1158 | SDL_Lock_EventThread(); | ||
1159 | |||
1160 | /* Check the combination of flags we were passed */ | ||
1161 | if ( flags & SDL_FULLSCREEN ) { | ||
1162 | /* Clear fullscreen flag if not supported */ | ||
1163 | if ( SDL_windowid ) { | ||
1164 | flags &= ~SDL_FULLSCREEN; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | /* Flush any delayed updates */ | ||
1169 | XSync(GFX_Display, False); | ||
1170 | |||
1171 | /* Set up the X11 window */ | ||
1172 | saved_flags = current->flags; | ||
1173 | if ( (SDL_Window) && ((saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL)) | ||
1174 | && (bpp == current->format->BitsPerPixel) | ||
1175 | && ((saved_flags&SDL_NOFRAME) == (flags&SDL_NOFRAME)) ) { | ||
1176 | if (X11_ResizeWindow(this, current, width, height, flags) < 0) { | ||
1177 | current = NULL; | ||
1178 | goto done; | ||
1179 | } | ||
1180 | X11_PendingConfigureNotifyWidth = width; | ||
1181 | X11_PendingConfigureNotifyHeight = height; | ||
1182 | } else { | ||
1183 | if (X11_CreateWindow(this,current,width,height,bpp,flags) < 0) { | ||
1184 | current = NULL; | ||
1185 | goto done; | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | /* Update the internal keyboard state */ | ||
1190 | X11_SetKeyboardState(SDL_Display, NULL); | ||
1191 | |||
1192 | /* When the window is first mapped, ignore non-modifier keys */ | ||
1193 | if ( !current->w && !current->h ) { | ||
1194 | Uint8 *keys = SDL_GetKeyState(NULL); | ||
1195 | int i; | ||
1196 | for ( i = 0; i < SDLK_LAST; ++i ) { | ||
1197 | switch (i) { | ||
1198 | case SDLK_NUMLOCK: | ||
1199 | case SDLK_CAPSLOCK: | ||
1200 | case SDLK_LCTRL: | ||
1201 | case SDLK_RCTRL: | ||
1202 | case SDLK_LSHIFT: | ||
1203 | case SDLK_RSHIFT: | ||
1204 | case SDLK_LALT: | ||
1205 | case SDLK_RALT: | ||
1206 | case SDLK_LMETA: | ||
1207 | case SDLK_RMETA: | ||
1208 | case SDLK_MODE: | ||
1209 | break; | ||
1210 | default: | ||
1211 | keys[i] = SDL_RELEASED; | ||
1212 | break; | ||
1213 | } | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1217 | /* Set up the new mode framebuffer */ | ||
1218 | if ( ((current->w != width) || (current->h != height)) || | ||
1219 | ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) { | ||
1220 | current->w = width; | ||
1221 | current->h = height; | ||
1222 | current->pitch = SDL_CalculatePitch(current); | ||
1223 | if (X11_ResizeImage(this, current, flags) < 0) { | ||
1224 | current = NULL; | ||
1225 | goto done; | ||
1226 | } | ||
1227 | } | ||
1228 | |||
1229 | /* Clear these flags and set them only if they are in the new set. */ | ||
1230 | current->flags &= ~(SDL_RESIZABLE|SDL_NOFRAME); | ||
1231 | current->flags |= (flags&(SDL_RESIZABLE|SDL_NOFRAME)); | ||
1232 | |||
1233 | done: | ||
1234 | /* Release the event thread */ | ||
1235 | XSync(SDL_Display, False); | ||
1236 | SDL_Unlock_EventThread(); | ||
1237 | |||
1238 | /* We're done! */ | ||
1239 | return(current); | ||
1240 | } | ||
1241 | |||
1242 | static int X11_ToggleFullScreen(_THIS, int on) | ||
1243 | { | ||
1244 | Uint32 event_thread; | ||
1245 | |||
1246 | /* Don't switch if we don't own the window */ | ||
1247 | if ( SDL_windowid ) { | ||
1248 | return(0); | ||
1249 | } | ||
1250 | |||
1251 | /* Don't lock if we are the event thread */ | ||
1252 | event_thread = SDL_EventThreadID(); | ||
1253 | if ( event_thread && (SDL_ThreadID() == event_thread) ) { | ||
1254 | event_thread = 0; | ||
1255 | } | ||
1256 | if ( event_thread ) { | ||
1257 | SDL_Lock_EventThread(); | ||
1258 | } | ||
1259 | if ( on ) { | ||
1260 | this->screen->flags |= SDL_FULLSCREEN; | ||
1261 | X11_EnterFullScreen(this); | ||
1262 | } else { | ||
1263 | this->screen->flags &= ~SDL_FULLSCREEN; | ||
1264 | X11_LeaveFullScreen(this); | ||
1265 | } | ||
1266 | X11_RefreshDisplay(this); | ||
1267 | if ( event_thread ) { | ||
1268 | SDL_Unlock_EventThread(); | ||
1269 | } | ||
1270 | SDL_ResetKeyboard(); | ||
1271 | return(1); | ||
1272 | } | ||
1273 | |||
1274 | /* Update the current mouse state and position */ | ||
1275 | static void X11_UpdateMouse(_THIS) | ||
1276 | { | ||
1277 | Window u1; int u2; | ||
1278 | Window current_win; | ||
1279 | int x, y; | ||
1280 | unsigned int mask; | ||
1281 | |||
1282 | /* Lock the event thread, in multi-threading environments */ | ||
1283 | SDL_Lock_EventThread(); | ||
1284 | if ( XQueryPointer(SDL_Display, SDL_Window, &u1, ¤t_win, | ||
1285 | &u2, &u2, &x, &y, &mask) ) { | ||
1286 | if ( (x >= 0) && (x < SDL_VideoSurface->w) && | ||
1287 | (y >= 0) && (y < SDL_VideoSurface->h) ) { | ||
1288 | SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | ||
1289 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
1290 | } else { | ||
1291 | SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); | ||
1292 | } | ||
1293 | } | ||
1294 | SDL_Unlock_EventThread(); | ||
1295 | } | ||
1296 | |||
1297 | /* simple colour distance metric. Supposed to be better than a plain | ||
1298 | Euclidian distance anyway. */ | ||
1299 | #define COLOUR_FACTOR 3 | ||
1300 | #define LIGHT_FACTOR 1 | ||
1301 | #define COLOUR_DIST(r1, g1, b1, r2, g2, b2) \ | ||
1302 | (COLOUR_FACTOR * (abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)) \ | ||
1303 | + LIGHT_FACTOR * abs(r1 + g1 + b1 - (r2 + g2 + b2))) | ||
1304 | |||
1305 | static void allocate_nearest(_THIS, SDL_Color *colors, | ||
1306 | SDL_Color *want, int nwant) | ||
1307 | { | ||
1308 | /* | ||
1309 | * There is no way to know which ones to choose from, so we retrieve | ||
1310 | * the entire colormap and try the nearest possible, until we find one | ||
1311 | * that is shared. | ||
1312 | */ | ||
1313 | XColor all[256]; | ||
1314 | int i; | ||
1315 | for(i = 0; i < 256; i++) | ||
1316 | all[i].pixel = i; | ||
1317 | /* | ||
1318 | * XQueryColors sets the flags in the XColor struct, so we use | ||
1319 | * that to keep track of which colours are available | ||
1320 | */ | ||
1321 | XQueryColors(GFX_Display, SDL_XColorMap, all, 256); | ||
1322 | |||
1323 | for(i = 0; i < nwant; i++) { | ||
1324 | XColor *c; | ||
1325 | int j; | ||
1326 | int best = 0; | ||
1327 | int mindist = 0x7fffffff; | ||
1328 | int ri = want[i].r; | ||
1329 | int gi = want[i].g; | ||
1330 | int bi = want[i].b; | ||
1331 | for(j = 0; j < 256; j++) { | ||
1332 | int rj, gj, bj, d2; | ||
1333 | if(!all[j].flags) | ||
1334 | continue; /* unavailable colour cell */ | ||
1335 | rj = all[j].red >> 8; | ||
1336 | gj = all[j].green >> 8; | ||
1337 | bj = all[j].blue >> 8; | ||
1338 | d2 = COLOUR_DIST(ri, gi, bi, rj, gj, bj); | ||
1339 | if(d2 < mindist) { | ||
1340 | mindist = d2; | ||
1341 | best = j; | ||
1342 | } | ||
1343 | } | ||
1344 | if(SDL_XPixels[best]) | ||
1345 | continue; /* already allocated, waste no more time */ | ||
1346 | c = all + best; | ||
1347 | if(XAllocColor(GFX_Display, SDL_XColorMap, c)) { | ||
1348 | /* got it */ | ||
1349 | colors[c->pixel].r = c->red >> 8; | ||
1350 | colors[c->pixel].g = c->green >> 8; | ||
1351 | colors[c->pixel].b = c->blue >> 8; | ||
1352 | ++SDL_XPixels[c->pixel]; | ||
1353 | } else { | ||
1354 | /* | ||
1355 | * The colour couldn't be allocated, probably being | ||
1356 | * owned as a r/w cell by another client. Flag it as | ||
1357 | * unavailable and try again. The termination of the | ||
1358 | * loop is guaranteed since at least black and white | ||
1359 | * are always there. | ||
1360 | */ | ||
1361 | c->flags = 0; | ||
1362 | i--; | ||
1363 | } | ||
1364 | } | ||
1365 | } | ||
1366 | |||
1367 | int X11_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | ||
1368 | { | ||
1369 | int nrej = 0; | ||
1370 | |||
1371 | /* Check to make sure we have a colormap allocated */ | ||
1372 | if ( SDL_XPixels == NULL ) { | ||
1373 | return(0); | ||
1374 | } | ||
1375 | if ( (this->screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { | ||
1376 | /* private writable colormap: just set the colours we need */ | ||
1377 | XColor *xcmap; | ||
1378 | int i; | ||
1379 | xcmap = SDL_stack_alloc(XColor, ncolors); | ||
1380 | if(xcmap == NULL) | ||
1381 | return 0; | ||
1382 | for ( i=0; i<ncolors; ++i ) { | ||
1383 | xcmap[i].pixel = i + firstcolor; | ||
1384 | xcmap[i].red = (colors[i].r<<8)|colors[i].r; | ||
1385 | xcmap[i].green = (colors[i].g<<8)|colors[i].g; | ||
1386 | xcmap[i].blue = (colors[i].b<<8)|colors[i].b; | ||
1387 | xcmap[i].flags = (DoRed|DoGreen|DoBlue); | ||
1388 | } | ||
1389 | XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); | ||
1390 | XSync(GFX_Display, False); | ||
1391 | SDL_stack_free(xcmap); | ||
1392 | } else { | ||
1393 | /* | ||
1394 | * Shared colormap: We only allocate read-only cells, which | ||
1395 | * increases the likelyhood of colour sharing with other | ||
1396 | * clients. The pixel values will almost certainly be | ||
1397 | * different from the requested ones, so the user has to | ||
1398 | * walk the colormap and see which index got what colour. | ||
1399 | * | ||
1400 | * We can work directly with the logical palette since it | ||
1401 | * has already been set when we get here. | ||
1402 | */ | ||
1403 | SDL_Color *want, *reject; | ||
1404 | unsigned long *freelist; | ||
1405 | int i; | ||
1406 | int nfree = 0; | ||
1407 | int nc = this->screen->format->palette->ncolors; | ||
1408 | colors = this->screen->format->palette->colors; | ||
1409 | freelist = SDL_stack_alloc(unsigned long, nc); | ||
1410 | /* make sure multiple allocations of the same cell are freed */ | ||
1411 | for(i = 0; i < ncolors; i++) { | ||
1412 | int pixel = firstcolor + i; | ||
1413 | while(SDL_XPixels[pixel]) { | ||
1414 | freelist[nfree++] = pixel; | ||
1415 | --SDL_XPixels[pixel]; | ||
1416 | } | ||
1417 | } | ||
1418 | XFreeColors(GFX_Display, SDL_XColorMap, freelist, nfree, 0); | ||
1419 | SDL_stack_free(freelist); | ||
1420 | |||
1421 | want = SDL_stack_alloc(SDL_Color, ncolors); | ||
1422 | reject = SDL_stack_alloc(SDL_Color, ncolors); | ||
1423 | SDL_memcpy(want, colors + firstcolor, ncolors * sizeof(SDL_Color)); | ||
1424 | /* make sure the user isn't fooled by her own wishes | ||
1425 | (black is safe, always available in the default colormap) */ | ||
1426 | SDL_memset(colors + firstcolor, 0, ncolors * sizeof(SDL_Color)); | ||
1427 | |||
1428 | /* now try to allocate the colours */ | ||
1429 | for(i = 0; i < ncolors; i++) { | ||
1430 | XColor col; | ||
1431 | col.red = want[i].r << 8; | ||
1432 | col.green = want[i].g << 8; | ||
1433 | col.blue = want[i].b << 8; | ||
1434 | col.flags = DoRed | DoGreen | DoBlue; | ||
1435 | if(XAllocColor(GFX_Display, SDL_XColorMap, &col)) { | ||
1436 | /* We got the colour, or at least the nearest | ||
1437 | the hardware could get. */ | ||
1438 | colors[col.pixel].r = col.red >> 8; | ||
1439 | colors[col.pixel].g = col.green >> 8; | ||
1440 | colors[col.pixel].b = col.blue >> 8; | ||
1441 | ++SDL_XPixels[col.pixel]; | ||
1442 | } else { | ||
1443 | /* | ||
1444 | * no more free cells, add it to the list | ||
1445 | * of rejected colours | ||
1446 | */ | ||
1447 | reject[nrej++] = want[i]; | ||
1448 | } | ||
1449 | } | ||
1450 | if(nrej) | ||
1451 | allocate_nearest(this, colors, reject, nrej); | ||
1452 | SDL_stack_free(reject); | ||
1453 | SDL_stack_free(want); | ||
1454 | } | ||
1455 | return nrej == 0; | ||
1456 | } | ||
1457 | |||
1458 | int X11_SetGammaRamp(_THIS, Uint16 *ramp) | ||
1459 | { | ||
1460 | int i, ncolors; | ||
1461 | XColor xcmap[256]; | ||
1462 | |||
1463 | /* See if actually setting the gamma is supported */ | ||
1464 | if ( SDL_Visual->class != DirectColor ) { | ||
1465 | SDL_SetError("Gamma correction not supported on this visual"); | ||
1466 | return(-1); | ||
1467 | } | ||
1468 | |||
1469 | /* Calculate the appropriate palette for the given gamma ramp */ | ||
1470 | ncolors = SDL_Visual->map_entries; | ||
1471 | for ( i=0; i<ncolors; ++i ) { | ||
1472 | Uint8 c = (256 * i / ncolors); | ||
1473 | xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c); | ||
1474 | xcmap[i].red = ramp[0*256+c]; | ||
1475 | xcmap[i].green = ramp[1*256+c]; | ||
1476 | xcmap[i].blue = ramp[2*256+c]; | ||
1477 | xcmap[i].flags = (DoRed|DoGreen|DoBlue); | ||
1478 | } | ||
1479 | XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); | ||
1480 | XSync(GFX_Display, False); | ||
1481 | return(0); | ||
1482 | } | ||
1483 | |||
1484 | /* Note: If we are terminated, this could be called in the middle of | ||
1485 | another SDL video routine -- notably UpdateRects. | ||
1486 | */ | ||
1487 | void X11_VideoQuit(_THIS) | ||
1488 | { | ||
1489 | /* Shutdown everything that's still up */ | ||
1490 | /* The event thread should be done, so we can touch SDL_Display */ | ||
1491 | if ( SDL_Display != NULL ) { | ||
1492 | /* Flush any delayed updates */ | ||
1493 | XSync(GFX_Display, False); | ||
1494 | |||
1495 | /* Close the connection with the IM server */ | ||
1496 | #ifdef X_HAVE_UTF8_STRING | ||
1497 | if (SDL_IC != NULL) { | ||
1498 | XUnsetICFocus(SDL_IC); | ||
1499 | XDestroyIC(SDL_IC); | ||
1500 | SDL_IC = NULL; | ||
1501 | } | ||
1502 | if (SDL_IM != NULL) { | ||
1503 | XCloseIM(SDL_IM); | ||
1504 | SDL_IM = NULL; | ||
1505 | } | ||
1506 | #endif | ||
1507 | |||
1508 | /* Start shutting down the windows */ | ||
1509 | X11_DestroyImage(this, this->screen); | ||
1510 | X11_DestroyWindow(this, this->screen); | ||
1511 | X11_FreeVideoModes(this); | ||
1512 | if ( SDL_XColorMap != SDL_DisplayColormap ) { | ||
1513 | XFreeColormap(SDL_Display, SDL_XColorMap); | ||
1514 | } | ||
1515 | if ( SDL_iconcolors ) { | ||
1516 | unsigned long pixel; | ||
1517 | Colormap dcmap = DefaultColormap(SDL_Display, | ||
1518 | SDL_Screen); | ||
1519 | for(pixel = 0; pixel < 256; ++pixel) { | ||
1520 | while(SDL_iconcolors[pixel] > 0) { | ||
1521 | XFreeColors(GFX_Display, | ||
1522 | dcmap, &pixel, 1, 0); | ||
1523 | --SDL_iconcolors[pixel]; | ||
1524 | } | ||
1525 | } | ||
1526 | SDL_free(SDL_iconcolors); | ||
1527 | SDL_iconcolors = NULL; | ||
1528 | } | ||
1529 | |||
1530 | /* Restore gamma settings if they've changed */ | ||
1531 | if ( SDL_GetAppState() & SDL_APPACTIVE ) { | ||
1532 | X11_SwapVidModeGamma(this); | ||
1533 | } | ||
1534 | |||
1535 | /* Free that blank cursor */ | ||
1536 | if ( SDL_BlankCursor != NULL ) { | ||
1537 | this->FreeWMCursor(this, SDL_BlankCursor); | ||
1538 | SDL_BlankCursor = NULL; | ||
1539 | } | ||
1540 | |||
1541 | /* Close the X11 graphics connection */ | ||
1542 | if ( GFX_Display != NULL ) { | ||
1543 | XCloseDisplay(GFX_Display); | ||
1544 | GFX_Display = NULL; | ||
1545 | } | ||
1546 | |||
1547 | /* Close the X11 display connection */ | ||
1548 | XCloseDisplay(SDL_Display); | ||
1549 | SDL_Display = NULL; | ||
1550 | |||
1551 | /* Reset the X11 error handlers */ | ||
1552 | if ( XIO_handler ) { | ||
1553 | XSetIOErrorHandler(XIO_handler); | ||
1554 | } | ||
1555 | if ( X_handler ) { | ||
1556 | XSetErrorHandler(X_handler); | ||
1557 | } | ||
1558 | |||
1559 | /* Unload GL library after X11 shuts down */ | ||
1560 | X11_GL_UnloadLibrary(this); | ||
1561 | } | ||
1562 | if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { | ||
1563 | /* Direct screen access, no memory buffer */ | ||
1564 | this->screen->pixels = NULL; | ||
1565 | } | ||
1566 | |||
1567 | #if SDL_VIDEO_DRIVER_X11_XME | ||
1568 | XiGMiscDestroy(); | ||
1569 | #endif | ||
1570 | } | ||
1571 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11video.h b/apps/plugins/sdl/src/video/x11/SDL_x11video.h deleted file mode 100644 index f347560d6d..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11video.h +++ /dev/null | |||
@@ -1,214 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_x11video_h | ||
25 | #define _SDL_x11video_h | ||
26 | |||
27 | #include <X11/Xlib.h> | ||
28 | #include <X11/Xutil.h> | ||
29 | #include <X11/Xatom.h> | ||
30 | |||
31 | #include "SDL_mouse.h" | ||
32 | #include "../SDL_sysvideo.h" | ||
33 | |||
34 | #if SDL_VIDEO_DRIVER_X11_DGAMOUSE | ||
35 | #include "../Xext/extensions/xf86dga.h" | ||
36 | #endif | ||
37 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
38 | #include "../Xext/extensions/Xinerama.h" | ||
39 | #endif | ||
40 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
41 | #include <X11/extensions/Xrandr.h> | ||
42 | #endif | ||
43 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
44 | #include "../Xext/extensions/xf86vmode.h" | ||
45 | #endif | ||
46 | #if SDL_VIDEO_DRIVER_X11_XME | ||
47 | #include "../Xext/extensions/xme.h" | ||
48 | #endif | ||
49 | |||
50 | #include "SDL_x11dyn.h" | ||
51 | |||
52 | /* Hidden "this" pointer for the video functions */ | ||
53 | #define _THIS SDL_VideoDevice *this | ||
54 | |||
55 | /* Private display data */ | ||
56 | struct SDL_PrivateVideoData { | ||
57 | int local_X11; /* Flag: true if local display */ | ||
58 | Display *X11_Display; /* Used for events and window management */ | ||
59 | Display *GFX_Display; /* Used for graphics and colormap stuff */ | ||
60 | Visual *SDL_Visual; /* The visual used by our window */ | ||
61 | Window WMwindow; /* Input window, managed by window manager */ | ||
62 | Window FSwindow; /* Fullscreen window, completely unmanaged */ | ||
63 | Window SDL_Window; /* Shared by both displays (no X security?) */ | ||
64 | Atom WM_DELETE_WINDOW; /* "close-window" protocol atom */ | ||
65 | WMcursor *BlankCursor; /* The invisible cursor */ | ||
66 | XIM X11_IM; /* Used to communicate with the input method (IM) server */ | ||
67 | XIC X11_IC; /* Used for retaining the state, properties, and semantics of communication with the input method (IM) server */ | ||
68 | |||
69 | char *SDL_windowid; /* Flag: true if we have been passed a window */ | ||
70 | |||
71 | /* Direct Graphics Access extension information */ | ||
72 | int using_dga; | ||
73 | |||
74 | #ifndef NO_SHARED_MEMORY | ||
75 | /* MIT shared memory extension information */ | ||
76 | int use_mitshm; | ||
77 | XShmSegmentInfo shminfo; | ||
78 | #endif | ||
79 | |||
80 | /* The variables used for displaying graphics */ | ||
81 | XImage *Ximage; /* The X image for our window */ | ||
82 | GC gc; /* The graphic context for drawing */ | ||
83 | |||
84 | /* The current width and height of the fullscreen mode */ | ||
85 | int window_w; | ||
86 | int window_h; | ||
87 | |||
88 | /* Support for internal mouse warping */ | ||
89 | struct { | ||
90 | int x; | ||
91 | int y; | ||
92 | } mouse_last; | ||
93 | struct { | ||
94 | int numerator; | ||
95 | int denominator; | ||
96 | int threshold; | ||
97 | } mouse_accel; | ||
98 | int mouse_relative; | ||
99 | |||
100 | /* The current list of available video modes */ | ||
101 | SDL_Rect **modelist; | ||
102 | |||
103 | /* available visuals of interest to us, sorted deepest first */ | ||
104 | struct { | ||
105 | Visual *visual; | ||
106 | int depth; /* number of significant bits/pixel */ | ||
107 | int bpp; /* pixel quantum in bits */ | ||
108 | } visuals[2*5]; /* at most 2 entries for 8, 15, 16, 24, 32 */ | ||
109 | int nvisuals; | ||
110 | |||
111 | Visual *vis; /* current visual in use */ | ||
112 | int depth; /* current visual depth (not bpp) */ | ||
113 | |||
114 | /* Variables used by the X11 video mode code */ | ||
115 | #if SDL_VIDEO_DRIVER_X11_XINERAMA | ||
116 | SDL_NAME(XineramaScreenInfo) xinerama_info; | ||
117 | #endif | ||
118 | #if SDL_VIDEO_DRIVER_X11_XRANDR | ||
119 | XRRScreenConfiguration* screen_config; | ||
120 | int saved_size_id; | ||
121 | Rotation saved_rotation; | ||
122 | #endif | ||
123 | #if SDL_VIDEO_DRIVER_X11_VIDMODE | ||
124 | SDL_NAME(XF86VidModeModeInfo) saved_mode; | ||
125 | struct { | ||
126 | int x, y; | ||
127 | } saved_view; | ||
128 | #endif | ||
129 | #if SDL_VIDEO_DRIVER_X11_XME /* XiG XME fullscreen */ | ||
130 | XiGMiscResolutionInfo saved_res; | ||
131 | #endif | ||
132 | |||
133 | int use_xinerama; | ||
134 | int use_xrandr; | ||
135 | int use_vidmode; | ||
136 | int use_xme; | ||
137 | int currently_fullscreen; | ||
138 | |||
139 | /* Automatic mode switching support (entering/leaving fullscreen) */ | ||
140 | Uint32 switch_waiting; | ||
141 | Uint32 switch_time; | ||
142 | |||
143 | /* Prevent too many XSync() calls */ | ||
144 | int blit_queued; | ||
145 | |||
146 | /* Colormap handling */ | ||
147 | Colormap DisplayColormap; /* The default display colormap */ | ||
148 | Colormap XColorMap; /* The current window colormap */ | ||
149 | int *XPixels; /* pixels value allocation counts */ | ||
150 | float gamma_saved[3]; /* Saved gamma values for VidMode gamma */ | ||
151 | int gamma_changed; /* flag: has VidMode gamma been modified? */ | ||
152 | |||
153 | short *iconcolors; /* List of colors used by the icon */ | ||
154 | |||
155 | /* Screensaver settings */ | ||
156 | int allow_screensaver; | ||
157 | }; | ||
158 | |||
159 | /* Old variable names */ | ||
160 | #define local_X11 (this->hidden->local_X11) | ||
161 | #define SDL_Display (this->hidden->X11_Display) | ||
162 | #define GFX_Display (this->hidden->GFX_Display) | ||
163 | #define SDL_Screen DefaultScreen(this->hidden->X11_Display) | ||
164 | #define SDL_Visual (this->hidden->vis) | ||
165 | #define SDL_Root RootWindow(SDL_Display, SDL_Screen) | ||
166 | #define WMwindow (this->hidden->WMwindow) | ||
167 | #define FSwindow (this->hidden->FSwindow) | ||
168 | #define SDL_Window (this->hidden->SDL_Window) | ||
169 | #define WM_DELETE_WINDOW (this->hidden->WM_DELETE_WINDOW) | ||
170 | #define SDL_BlankCursor (this->hidden->BlankCursor) | ||
171 | #define SDL_IM (this->hidden->X11_IM) | ||
172 | #define SDL_IC (this->hidden->X11_IC) | ||
173 | #define SDL_windowid (this->hidden->SDL_windowid) | ||
174 | #define using_dga (this->hidden->using_dga) | ||
175 | #define use_mitshm (this->hidden->use_mitshm) | ||
176 | #define shminfo (this->hidden->shminfo) | ||
177 | #define SDL_Ximage (this->hidden->Ximage) | ||
178 | #define SDL_GC (this->hidden->gc) | ||
179 | #define window_w (this->hidden->window_w) | ||
180 | #define window_h (this->hidden->window_h) | ||
181 | #define mouse_last (this->hidden->mouse_last) | ||
182 | #define mouse_accel (this->hidden->mouse_accel) | ||
183 | #define mouse_relative (this->hidden->mouse_relative) | ||
184 | #define SDL_modelist (this->hidden->modelist) | ||
185 | #define xinerama_info (this->hidden->xinerama_info) | ||
186 | #define saved_mode (this->hidden->saved_mode) | ||
187 | #define saved_view (this->hidden->saved_view) | ||
188 | #define saved_res (this->hidden->saved_res) | ||
189 | #define screen_config (this->hidden->screen_config) | ||
190 | #define saved_size_id (this->hidden->saved_size_id) | ||
191 | #define saved_rotation (this->hidden->saved_rotation) | ||
192 | #define use_xinerama (this->hidden->use_xinerama) | ||
193 | #define use_vidmode (this->hidden->use_vidmode) | ||
194 | #define use_xrandr (this->hidden->use_xrandr) | ||
195 | #define use_xme (this->hidden->use_xme) | ||
196 | #define currently_fullscreen (this->hidden->currently_fullscreen) | ||
197 | #define switch_waiting (this->hidden->switch_waiting) | ||
198 | #define switch_time (this->hidden->switch_time) | ||
199 | #define blit_queued (this->hidden->blit_queued) | ||
200 | #define SDL_DisplayColormap (this->hidden->DisplayColormap) | ||
201 | #define SDL_PrivateColormap (this->hidden->PrivateColormap) | ||
202 | #define SDL_XColorMap (this->hidden->XColorMap) | ||
203 | #define SDL_XPixels (this->hidden->XPixels) | ||
204 | #define gamma_saved (this->hidden->gamma_saved) | ||
205 | #define gamma_changed (this->hidden->gamma_changed) | ||
206 | #define SDL_iconcolors (this->hidden->iconcolors) | ||
207 | #define allow_screensaver (this->hidden->allow_screensaver) | ||
208 | |||
209 | /* Some versions of XFree86 have bugs - detect if this is one of them */ | ||
210 | #define BUGGY_XFREE86(condition, buggy_version) \ | ||
211 | ((SDL_strcmp(ServerVendor(SDL_Display), "The XFree86 Project, Inc") == 0) && \ | ||
212 | (VendorRelease(SDL_Display) condition buggy_version)) | ||
213 | |||
214 | #endif /* _SDL_x11video_h */ | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11wm.c b/apps/plugins/sdl/src/video/x11/SDL_x11wm.c deleted file mode 100644 index 14c816b942..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11wm.c +++ /dev/null | |||
@@ -1,434 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <X11/Xlib.h> | ||
25 | #include <X11/Xutil.h> | ||
26 | |||
27 | #include "SDL_version.h" | ||
28 | #include "SDL_timer.h" | ||
29 | #include "SDL_video.h" | ||
30 | #include "SDL_syswm.h" | ||
31 | #include "../SDL_pixels_c.h" | ||
32 | #include "../../events/SDL_events_c.h" | ||
33 | #include "SDL_x11modes_c.h" | ||
34 | #include "SDL_x11wm_c.h" | ||
35 | |||
36 | static Uint8 reverse_byte(Uint8 x) | ||
37 | { | ||
38 | x = (x & 0xaa) >> 1 | (x & 0x55) << 1; | ||
39 | x = (x & 0xcc) >> 2 | (x & 0x33) << 2; | ||
40 | x = (x & 0xf0) >> 4 | (x & 0x0f) << 4; | ||
41 | return x; | ||
42 | } | ||
43 | |||
44 | void X11_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask) | ||
45 | { | ||
46 | SDL_Surface *sicon; | ||
47 | XWMHints *wmhints; | ||
48 | XImage *icon_image; | ||
49 | Pixmap icon_pixmap; | ||
50 | Pixmap mask_pixmap; | ||
51 | Window icon_window = None; | ||
52 | GC gc; | ||
53 | XGCValues GCvalues; | ||
54 | int i, dbpp; | ||
55 | SDL_Rect bounds; | ||
56 | Uint8 *LSBmask; | ||
57 | Visual *dvis; | ||
58 | char *p; | ||
59 | int masksize; | ||
60 | |||
61 | SDL_Lock_EventThread(); | ||
62 | |||
63 | /* The icon must use the default visual, depth and colormap of the | ||
64 | screen, so it might need a conversion */ | ||
65 | dvis = DefaultVisual(SDL_Display, SDL_Screen); | ||
66 | dbpp = DefaultDepth(SDL_Display, SDL_Screen); | ||
67 | for(i = 0; i < this->hidden->nvisuals; i++) { | ||
68 | if(this->hidden->visuals[i].visual == dvis) { | ||
69 | dbpp = this->hidden->visuals[i].bpp; | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | /* The Visual struct is supposed to be opaque but we cheat a little */ | ||
75 | sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h, | ||
76 | dbpp, | ||
77 | dvis->red_mask, dvis->green_mask, | ||
78 | dvis->blue_mask, 0); | ||
79 | if ( sicon == NULL ) | ||
80 | goto done; | ||
81 | |||
82 | if(dbpp == 8) { | ||
83 | /* Default visual is 8bit; we need to allocate colours from | ||
84 | the default colormap */ | ||
85 | SDL_Color want[256], got[256]; | ||
86 | int nwant; | ||
87 | Colormap dcmap; | ||
88 | int missing; | ||
89 | dcmap = DefaultColormap(SDL_Display, SDL_Screen); | ||
90 | if(icon->format->palette) { | ||
91 | /* The icon has a palette as well - we just have to | ||
92 | find those colours */ | ||
93 | nwant = icon->format->palette->ncolors; | ||
94 | SDL_memcpy(want, icon->format->palette->colors, | ||
95 | nwant * sizeof want[0]); | ||
96 | } else { | ||
97 | /* try the standard 6x6x6 cube for lack of better | ||
98 | ideas */ | ||
99 | int r, g, b, i; | ||
100 | for(r = i = 0; r < 256; r += 0x33) | ||
101 | for(g = 0; g < 256; g += 0x33) | ||
102 | for(b = 0; b < 256; b += 0x33, i++) { | ||
103 | want[i].r = r; | ||
104 | want[i].g = g; | ||
105 | want[i].b = b; | ||
106 | } | ||
107 | nwant = 216; | ||
108 | } | ||
109 | if(SDL_iconcolors) { | ||
110 | /* free already allocated colours first */ | ||
111 | unsigned long freelist[512]; | ||
112 | int nfree = 0; | ||
113 | for(i = 0; i < 256; i++) { | ||
114 | while(SDL_iconcolors[i]) { | ||
115 | freelist[nfree++] = i; | ||
116 | SDL_iconcolors[i]--; | ||
117 | } | ||
118 | } | ||
119 | XFreeColors(GFX_Display, dcmap, freelist, nfree, 0); | ||
120 | } | ||
121 | if(!SDL_iconcolors) | ||
122 | SDL_iconcolors = SDL_malloc(256 * sizeof *SDL_iconcolors); | ||
123 | SDL_memset(SDL_iconcolors, 0, 256 * sizeof *SDL_iconcolors); | ||
124 | |||
125 | /* try to allocate the colours */ | ||
126 | SDL_memset(got, 0, sizeof got); | ||
127 | missing = 0; | ||
128 | for(i = 0; i < nwant; i++) { | ||
129 | XColor c; | ||
130 | c.red = want[i].r << 8; | ||
131 | c.green = want[i].g << 8; | ||
132 | c.blue = want[i].b << 8; | ||
133 | c.flags = DoRed | DoGreen | DoBlue; | ||
134 | if(XAllocColor(GFX_Display, dcmap, &c)) { | ||
135 | /* got the colour */ | ||
136 | SDL_iconcolors[c.pixel]++; | ||
137 | got[c.pixel] = want[i]; | ||
138 | } else { | ||
139 | missing = 1; | ||
140 | } | ||
141 | } | ||
142 | if(missing) { | ||
143 | /* Some colours were apparently missing, so we just | ||
144 | allocate all the rest as well */ | ||
145 | XColor cols[256]; | ||
146 | for(i = 0; i < 256; i++) | ||
147 | cols[i].pixel = i; | ||
148 | XQueryColors(GFX_Display, dcmap, cols, 256); | ||
149 | for(i = 0; i < 256; i++) { | ||
150 | got[i].r = cols[i].red >> 8; | ||
151 | got[i].g = cols[i].green >> 8; | ||
152 | got[i].b = cols[i].blue >> 8; | ||
153 | if(!SDL_iconcolors[i]) { | ||
154 | if(XAllocColor(GFX_Display, dcmap, | ||
155 | cols + i)) { | ||
156 | SDL_iconcolors[i] = 1; | ||
157 | } else { | ||
158 | /* index not available */ | ||
159 | got[i].r = 0; | ||
160 | got[i].g = 0; | ||
161 | got[i].b = 0; | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | |||
167 | SDL_SetColors(sicon, got, 0, 256); | ||
168 | } | ||
169 | |||
170 | bounds.x = 0; | ||
171 | bounds.y = 0; | ||
172 | bounds.w = icon->w; | ||
173 | bounds.h = icon->h; | ||
174 | if ( SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0 ) | ||
175 | goto done; | ||
176 | |||
177 | /* We need the mask as given, except in LSBfirst format instead of | ||
178 | MSBfirst. Reverse the bits in each byte. */ | ||
179 | masksize = ((sicon->w + 7) >> 3) * sicon->h; | ||
180 | LSBmask = SDL_malloc(masksize); | ||
181 | if ( LSBmask == NULL ) { | ||
182 | goto done; | ||
183 | } | ||
184 | SDL_memset(LSBmask, 0, masksize); | ||
185 | for(i = 0; i < masksize; i++) | ||
186 | LSBmask[i] = reverse_byte(mask[i]); | ||
187 | mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow, | ||
188 | (char *)LSBmask, | ||
189 | sicon->w, sicon->h, | ||
190 | 1L, 0L, 1); | ||
191 | |||
192 | /* Transfer the image to an X11 pixmap */ | ||
193 | icon_image = XCreateImage(SDL_Display, | ||
194 | DefaultVisual(SDL_Display, SDL_Screen), | ||
195 | DefaultDepth(SDL_Display, SDL_Screen), | ||
196 | ZPixmap, 0, sicon->pixels, | ||
197 | sicon->w, sicon->h, | ||
198 | 32, 0); | ||
199 | icon_image->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) | ||
200 | ? MSBFirst : LSBFirst; | ||
201 | icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h, | ||
202 | DefaultDepth(SDL_Display, SDL_Screen)); | ||
203 | gc = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues); | ||
204 | XPutImage(SDL_Display, icon_pixmap, gc, icon_image, | ||
205 | 0, 0, 0, 0, sicon->w, sicon->h); | ||
206 | XFreeGC(SDL_Display, gc); | ||
207 | XDestroyImage(icon_image); | ||
208 | SDL_free(LSBmask); | ||
209 | sicon->pixels = NULL; | ||
210 | |||
211 | /* Some buggy window managers (some versions of Enlightenment, it | ||
212 | seems) need an icon window *and* icon pixmap to work properly, while | ||
213 | it screws up others. The default is only to use a pixmap. */ | ||
214 | p = SDL_getenv("SDL_VIDEO_X11_ICONWIN"); | ||
215 | if(p && *p) { | ||
216 | icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root, | ||
217 | 0, 0, sicon->w, sicon->h, 0, | ||
218 | CopyFromParent, | ||
219 | CopyFromParent); | ||
220 | XSetWindowBackgroundPixmap(SDL_Display, icon_window, | ||
221 | icon_pixmap); | ||
222 | XClearWindow(SDL_Display, icon_window); | ||
223 | } | ||
224 | |||
225 | /* Set the window icon to the icon pixmap (and icon window) */ | ||
226 | wmhints = XAllocWMHints(); | ||
227 | wmhints->flags = (IconPixmapHint | IconMaskHint | InputHint); | ||
228 | wmhints->icon_pixmap = icon_pixmap; | ||
229 | wmhints->icon_mask = mask_pixmap; | ||
230 | wmhints->input = True; | ||
231 | if(icon_window != None) { | ||
232 | wmhints->flags |= IconWindowHint; | ||
233 | wmhints->icon_window = icon_window; | ||
234 | } | ||
235 | XSetWMHints(SDL_Display, WMwindow, wmhints); | ||
236 | XFree(wmhints); | ||
237 | XSync(SDL_Display, False); | ||
238 | |||
239 | done: | ||
240 | SDL_Unlock_EventThread(); | ||
241 | SDL_FreeSurface(sicon); | ||
242 | } | ||
243 | |||
244 | void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon) | ||
245 | { | ||
246 | XTextProperty titleprop, iconprop; | ||
247 | Status status; | ||
248 | |||
249 | #ifdef X_HAVE_UTF8_STRING | ||
250 | Atom _NET_WM_NAME = 0; | ||
251 | Atom _NET_WM_ICON_NAME = 0; | ||
252 | |||
253 | /* Look up some useful Atoms */ | ||
254 | if (SDL_X11_HAVE_UTF8) { | ||
255 | _NET_WM_NAME = XInternAtom(SDL_Display, "_NET_WM_NAME", False); | ||
256 | _NET_WM_ICON_NAME = XInternAtom(SDL_Display, "_NET_WM_ICON_NAME", False); | ||
257 | } | ||
258 | #endif | ||
259 | |||
260 | if ( title != NULL ) { | ||
261 | char *title_locale = SDL_iconv_utf8_locale(title); | ||
262 | if ( !title_locale ) { | ||
263 | SDL_OutOfMemory(); | ||
264 | return; | ||
265 | } | ||
266 | status = XStringListToTextProperty(&title_locale, 1, &titleprop); | ||
267 | SDL_free(title_locale); | ||
268 | if ( status ) { | ||
269 | XSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME); | ||
270 | XFree(titleprop.value); | ||
271 | } | ||
272 | #ifdef X_HAVE_UTF8_STRING | ||
273 | if (SDL_X11_HAVE_UTF8) { | ||
274 | status = Xutf8TextListToTextProperty(SDL_Display, | ||
275 | (char **)&title, 1, XUTF8StringStyle, &titleprop); | ||
276 | if ( status == Success ) { | ||
277 | XSetTextProperty(SDL_Display, WMwindow, &titleprop, _NET_WM_NAME); | ||
278 | XFree(titleprop.value); | ||
279 | } | ||
280 | } | ||
281 | #endif | ||
282 | } | ||
283 | if ( icon != NULL ) { | ||
284 | char *icon_locale = SDL_iconv_utf8_locale(icon); | ||
285 | if ( !icon_locale ) { | ||
286 | SDL_OutOfMemory(); | ||
287 | return; | ||
288 | } | ||
289 | status = XStringListToTextProperty(&icon_locale, 1, &iconprop); | ||
290 | SDL_free(icon_locale); | ||
291 | if ( status ) { | ||
292 | XSetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME); | ||
293 | XFree(iconprop.value); | ||
294 | } | ||
295 | #ifdef X_HAVE_UTF8_STRING | ||
296 | if (SDL_X11_HAVE_UTF8) { | ||
297 | status = Xutf8TextListToTextProperty(SDL_Display, | ||
298 | (char **)&icon, 1, XUTF8StringStyle, &iconprop); | ||
299 | if ( status == Success ) { | ||
300 | XSetTextProperty(SDL_Display, WMwindow, &iconprop, _NET_WM_ICON_NAME); | ||
301 | XFree(iconprop.value); | ||
302 | } | ||
303 | } | ||
304 | #endif | ||
305 | } | ||
306 | XSync(SDL_Display, False); | ||
307 | } | ||
308 | |||
309 | void X11_SetCaption(_THIS, const char *title, const char *icon) | ||
310 | { | ||
311 | SDL_Lock_EventThread(); | ||
312 | X11_SetCaptionNoLock(this, title, icon); | ||
313 | SDL_Unlock_EventThread(); | ||
314 | } | ||
315 | |||
316 | /* Iconify the window */ | ||
317 | int X11_IconifyWindow(_THIS) | ||
318 | { | ||
319 | int result; | ||
320 | |||
321 | SDL_Lock_EventThread(); | ||
322 | result = XIconifyWindow(SDL_Display, WMwindow, SDL_Screen); | ||
323 | XSync(SDL_Display, False); | ||
324 | SDL_Unlock_EventThread(); | ||
325 | return(result); | ||
326 | } | ||
327 | |||
328 | SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode) | ||
329 | { | ||
330 | int result; | ||
331 | |||
332 | if ( this->screen == NULL || SDL_Display == NULL ) { | ||
333 | return(SDL_GRAB_OFF); | ||
334 | } | ||
335 | if ( ! SDL_Window ) { | ||
336 | return(mode); /* Will be set later on mode switch */ | ||
337 | } | ||
338 | if ( mode == SDL_GRAB_OFF ) { | ||
339 | XUngrabPointer(SDL_Display, CurrentTime); | ||
340 | XUngrabKeyboard(SDL_Display, CurrentTime); | ||
341 | } else { | ||
342 | if ( this->screen->flags & SDL_FULLSCREEN ) { | ||
343 | /* Unbind the mouse from the fullscreen window */ | ||
344 | XUngrabPointer(SDL_Display, CurrentTime); | ||
345 | } | ||
346 | /* Try to grab the mouse */ | ||
347 | #if 0 /* We'll wait here until we actually grab, otherwise behavior undefined */ | ||
348 | for ( numtries = 0; numtries < 10; ++numtries ) { | ||
349 | #else | ||
350 | for ( ; ; ) { | ||
351 | #endif | ||
352 | result = XGrabPointer(SDL_Display, SDL_Window, True, 0, | ||
353 | GrabModeAsync, GrabModeAsync, | ||
354 | SDL_Window, None, CurrentTime); | ||
355 | if ( result == GrabSuccess ) { | ||
356 | break; | ||
357 | } | ||
358 | SDL_Delay(100); | ||
359 | } | ||
360 | if ( result != GrabSuccess ) { | ||
361 | /* Uh, oh, what do we do here? */ ; | ||
362 | } | ||
363 | /* Now grab the keyboard */ | ||
364 | XGrabKeyboard(SDL_Display, WMwindow, True, | ||
365 | GrabModeAsync, GrabModeAsync, CurrentTime); | ||
366 | |||
367 | /* Raise the window if we grab the mouse */ | ||
368 | if ( !(this->screen->flags & SDL_FULLSCREEN) ) | ||
369 | XRaiseWindow(SDL_Display, WMwindow); | ||
370 | |||
371 | /* Make sure we register input focus */ | ||
372 | SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); | ||
373 | /* Since we grabbed the pointer, we have mouse focus, too. */ | ||
374 | SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | ||
375 | } | ||
376 | XSync(SDL_Display, False); | ||
377 | |||
378 | return(mode); | ||
379 | } | ||
380 | |||
381 | SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode) | ||
382 | { | ||
383 | SDL_Lock_EventThread(); | ||
384 | mode = X11_GrabInputNoLock(this, mode); | ||
385 | SDL_Unlock_EventThread(); | ||
386 | |||
387 | return(mode); | ||
388 | } | ||
389 | |||
390 | /* If 'info' is the right version, this function fills it and returns 1. | ||
391 | Otherwise, in case of a version mismatch, it returns -1. | ||
392 | */ | ||
393 | static void lock_display(void) | ||
394 | { | ||
395 | SDL_Lock_EventThread(); | ||
396 | } | ||
397 | static void unlock_display(void) | ||
398 | { | ||
399 | /* Make sure any X11 transactions are completed */ | ||
400 | SDL_VideoDevice *this = current_video; | ||
401 | XSync(SDL_Display, False); | ||
402 | SDL_Unlock_EventThread(); | ||
403 | } | ||
404 | |||
405 | #include <stdio.h> | ||
406 | int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info) | ||
407 | { | ||
408 | if ( info->version.major <= SDL_MAJOR_VERSION ) { | ||
409 | info->subsystem = SDL_SYSWM_X11; | ||
410 | info->info.x11.display = SDL_Display; | ||
411 | info->info.x11.window = SDL_Window; | ||
412 | if ( SDL_VERSIONNUM(info->version.major, | ||
413 | info->version.minor, | ||
414 | info->version.patch) >= 1002 ) { | ||
415 | info->info.x11.fswindow = FSwindow; | ||
416 | info->info.x11.wmwindow = WMwindow; | ||
417 | } | ||
418 | |||
419 | |||
420 | if ( SDL_VERSIONNUM(info->version.major, | ||
421 | info->version.minor, | ||
422 | info->version.patch) >= 1212 ) { | ||
423 | info->info.x11.gfxdisplay = GFX_Display; | ||
424 | } | ||
425 | |||
426 | info->info.x11.lock_func = lock_display; | ||
427 | info->info.x11.unlock_func = unlock_display; | ||
428 | return(1); | ||
429 | } else { | ||
430 | SDL_SetError("Application not compiled with SDL %d.%d\n", | ||
431 | SDL_MAJOR_VERSION, SDL_MINOR_VERSION); | ||
432 | return(-1); | ||
433 | } | ||
434 | } | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11wm_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11wm_c.h deleted file mode 100644 index f85477bba1..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11wm_c.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_x11video.h" | ||
25 | |||
26 | /* Functions to be exported */ | ||
27 | extern void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon); | ||
28 | extern void X11_SetCaption(_THIS, const char *title, const char *icon); | ||
29 | extern void X11_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask); | ||
30 | extern int X11_IconifyWindow(_THIS); | ||
31 | extern SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode); | ||
32 | extern SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode); | ||
33 | extern int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info); | ||
34 | |||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11yuv.c b/apps/plugins/sdl/src/video/x11/SDL_x11yuv.c deleted file mode 100644 index 62698dfd9b..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11yuv.c +++ /dev/null | |||
@@ -1,538 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* This is the XFree86 Xv extension implementation of YUV video overlays */ | ||
25 | |||
26 | #if SDL_VIDEO_DRIVER_X11_XV | ||
27 | |||
28 | #include <X11/Xlib.h> | ||
29 | #ifndef NO_SHARED_MEMORY | ||
30 | #include <sys/ipc.h> | ||
31 | #include <sys/shm.h> | ||
32 | #include <X11/extensions/XShm.h> | ||
33 | #endif | ||
34 | #include "../Xext/extensions/Xvlib.h" | ||
35 | |||
36 | #include "SDL_x11yuv_c.h" | ||
37 | #include "../SDL_yuvfuncs.h" | ||
38 | |||
39 | #define XFREE86_REFRESH_HACK | ||
40 | #ifdef XFREE86_REFRESH_HACK | ||
41 | #include "SDL_x11image_c.h" | ||
42 | #endif | ||
43 | |||
44 | /* Workaround when pitch != width */ | ||
45 | #define PITCH_WORKAROUND | ||
46 | |||
47 | /* Workaround intel i810 video overlay waiting with failing until the | ||
48 | first Xv[Shm]PutImage call <sigh> */ | ||
49 | #define INTEL_XV_BADALLOC_WORKAROUND | ||
50 | |||
51 | /* Fix for the NVidia GeForce 2 - use the last available adaptor */ | ||
52 | /*#define USE_LAST_ADAPTOR*/ /* Apparently the NVidia drivers are fixed */ | ||
53 | |||
54 | /* The functions used to manipulate software video overlays */ | ||
55 | static struct private_yuvhwfuncs x11_yuvfuncs = { | ||
56 | X11_LockYUVOverlay, | ||
57 | X11_UnlockYUVOverlay, | ||
58 | X11_DisplayYUVOverlay, | ||
59 | X11_FreeYUVOverlay | ||
60 | }; | ||
61 | |||
62 | struct private_yuvhwdata { | ||
63 | int port; | ||
64 | #ifndef NO_SHARED_MEMORY | ||
65 | int yuv_use_mitshm; | ||
66 | XShmSegmentInfo yuvshm; | ||
67 | #endif | ||
68 | SDL_NAME(XvImage) *image; | ||
69 | }; | ||
70 | |||
71 | |||
72 | static int (*X_handler)(Display *, XErrorEvent *) = NULL; | ||
73 | |||
74 | #ifndef NO_SHARED_MEMORY | ||
75 | /* Shared memory error handler routine */ | ||
76 | static int shm_error; | ||
77 | static int shm_errhandler(Display *d, XErrorEvent *e) | ||
78 | { | ||
79 | if ( e->error_code == BadAccess ) { | ||
80 | shm_error = True; | ||
81 | return(0); | ||
82 | } else | ||
83 | return(X_handler(d,e)); | ||
84 | } | ||
85 | #endif /* !NO_SHARED_MEMORY */ | ||
86 | |||
87 | static int xv_error; | ||
88 | static int xv_errhandler(Display *d, XErrorEvent *e) | ||
89 | { | ||
90 | if ( e->error_code == BadMatch ) { | ||
91 | xv_error = True; | ||
92 | return(0); | ||
93 | } else | ||
94 | return(X_handler(d,e)); | ||
95 | } | ||
96 | |||
97 | #ifdef INTEL_XV_BADALLOC_WORKAROUND | ||
98 | static int intel_errhandler(Display *d, XErrorEvent *e) | ||
99 | { | ||
100 | if ( e->error_code == BadAlloc ) { | ||
101 | xv_error = True; | ||
102 | return(0); | ||
103 | } else | ||
104 | return(X_handler(d,e)); | ||
105 | } | ||
106 | |||
107 | static void X11_ClearYUVOverlay(SDL_Overlay *overlay) | ||
108 | { | ||
109 | int x,y; | ||
110 | |||
111 | switch (overlay->format) | ||
112 | { | ||
113 | case SDL_YV12_OVERLAY: | ||
114 | case SDL_IYUV_OVERLAY: | ||
115 | for (y = 0; y < overlay->h; y++) | ||
116 | memset(overlay->pixels[0] + y * overlay->pitches[0], | ||
117 | 0, overlay->w); | ||
118 | |||
119 | for (y = 0; y < (overlay->h / 2); y++) | ||
120 | { | ||
121 | memset(overlay->pixels[1] + y * overlay->pitches[1], | ||
122 | -128, overlay->w / 2); | ||
123 | memset(overlay->pixels[2] + y * overlay->pitches[2], | ||
124 | -128, overlay->w / 2); | ||
125 | } | ||
126 | break; | ||
127 | case SDL_YUY2_OVERLAY: | ||
128 | case SDL_YVYU_OVERLAY: | ||
129 | for (y = 0; y < overlay->h; y++) | ||
130 | { | ||
131 | for (x = 0; x < overlay->w; x += 2) | ||
132 | { | ||
133 | Uint8 *pixel_pair = overlay->pixels[0] + | ||
134 | y * overlay->pitches[0] + x * 2; | ||
135 | pixel_pair[0] = 0; | ||
136 | pixel_pair[1] = -128; | ||
137 | pixel_pair[2] = 0; | ||
138 | pixel_pair[3] = -128; | ||
139 | } | ||
140 | } | ||
141 | break; | ||
142 | case SDL_UYVY_OVERLAY: | ||
143 | for (y = 0; y < overlay->h; y++) | ||
144 | { | ||
145 | for (x = 0; x < overlay->w; x += 2) | ||
146 | { | ||
147 | Uint8 *pixel_pair = overlay->pixels[0] + | ||
148 | y * overlay->pitches[0] + x * 2; | ||
149 | pixel_pair[0] = -128; | ||
150 | pixel_pair[1] = 0; | ||
151 | pixel_pair[2] = -128; | ||
152 | pixel_pair[3] = 0; | ||
153 | } | ||
154 | } | ||
155 | break; | ||
156 | } | ||
157 | } | ||
158 | #endif | ||
159 | |||
160 | SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) | ||
161 | { | ||
162 | SDL_Overlay *overlay; | ||
163 | struct private_yuvhwdata *hwdata; | ||
164 | int xv_port; | ||
165 | unsigned int i, j, k; | ||
166 | unsigned int adaptors; | ||
167 | SDL_NAME(XvAdaptorInfo) *ainfo; | ||
168 | int bpp; | ||
169 | #ifndef NO_SHARED_MEMORY | ||
170 | XShmSegmentInfo *yuvshm; | ||
171 | #endif | ||
172 | #ifdef INTEL_XV_BADALLOC_WORKAROUND | ||
173 | int intel_adapter = False; | ||
174 | #endif | ||
175 | |||
176 | /* Look for the XVideo extension with a valid port for this format */ | ||
177 | xv_port = -1; | ||
178 | if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) && | ||
179 | (Success == SDL_NAME(XvQueryAdaptors)(GFX_Display, | ||
180 | RootWindow(GFX_Display, SDL_Screen), | ||
181 | &adaptors, &ainfo)) ) { | ||
182 | #ifdef USE_LAST_ADAPTOR | ||
183 | for ( i=0; i < adaptors; ++i ) | ||
184 | #else | ||
185 | for ( i=0; (i < adaptors) && (xv_port == -1); ++i ) | ||
186 | #endif /* USE_LAST_ADAPTOR */ | ||
187 | { | ||
188 | /* Check to see if the visual can be used */ | ||
189 | if ( BUGGY_XFREE86(<=, 4001) ) { | ||
190 | int visual_ok = 0; | ||
191 | for ( j=0; j<ainfo[i].num_formats; ++j ) { | ||
192 | if ( ainfo[i].formats[j].visual_id == | ||
193 | SDL_Visual->visualid ) { | ||
194 | visual_ok = 1; | ||
195 | break; | ||
196 | } | ||
197 | } | ||
198 | if ( ! visual_ok ) { | ||
199 | continue; | ||
200 | } | ||
201 | } | ||
202 | #ifdef INTEL_XV_BADALLOC_WORKAROUND | ||
203 | if ( !strcmp(ainfo[i].name, "Intel(R) Video Overla")) | ||
204 | intel_adapter = True; | ||
205 | else | ||
206 | intel_adapter = False; | ||
207 | #endif | ||
208 | if ( (ainfo[i].type & XvInputMask) && | ||
209 | (ainfo[i].type & XvImageMask) ) { | ||
210 | int num_formats; | ||
211 | SDL_NAME(XvImageFormatValues) *formats; | ||
212 | formats = SDL_NAME(XvListImageFormats)(GFX_Display, | ||
213 | ainfo[i].base_id, &num_formats); | ||
214 | #ifdef USE_LAST_ADAPTOR | ||
215 | for ( j=0; j < num_formats; ++j ) | ||
216 | #else | ||
217 | for ( j=0; (j < num_formats) && (xv_port == -1); ++j ) | ||
218 | #endif /* USE_LAST_ADAPTOR */ | ||
219 | { | ||
220 | if ( (Uint32)formats[j].id == format ) { | ||
221 | for ( k=0; k < ainfo[i].num_ports; ++k ) { | ||
222 | if ( Success == SDL_NAME(XvGrabPort)(GFX_Display, ainfo[i].base_id+k, CurrentTime) ) { | ||
223 | xv_port = ainfo[i].base_id+k; | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | if ( formats ) { | ||
230 | XFree(formats); | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | SDL_NAME(XvFreeAdaptorInfo)(ainfo); | ||
235 | } | ||
236 | |||
237 | /* Precalculate the bpp for the pitch workaround below */ | ||
238 | switch (format) { | ||
239 | /* Add any other cases we need to support... */ | ||
240 | case SDL_YUY2_OVERLAY: | ||
241 | case SDL_UYVY_OVERLAY: | ||
242 | case SDL_YVYU_OVERLAY: | ||
243 | bpp = 2; | ||
244 | break; | ||
245 | default: | ||
246 | bpp = 1; | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | #if 0 | ||
251 | /* | ||
252 | * !!! FIXME: | ||
253 | * "Here are some diffs for X11 and yuv. Note that the last part 2nd | ||
254 | * diff should probably be a new call to XvQueryAdaptorFree with ainfo | ||
255 | * and the number of adaptors, instead of the loop through like I did." | ||
256 | * | ||
257 | * ACHTUNG: This is broken! It looks like XvFreeAdaptorInfo does this | ||
258 | * for you, so we end up with a double-free. I need to look at this | ||
259 | * more closely... --ryan. | ||
260 | */ | ||
261 | for ( i=0; i < adaptors; ++i ) { | ||
262 | if (ainfo[i].name != NULL) Xfree(ainfo[i].name); | ||
263 | if (ainfo[i].formats != NULL) Xfree(ainfo[i].formats); | ||
264 | } | ||
265 | Xfree(ainfo); | ||
266 | #endif | ||
267 | |||
268 | if ( xv_port == -1 ) { | ||
269 | SDL_SetError("No available video ports for requested format"); | ||
270 | return(NULL); | ||
271 | } | ||
272 | |||
273 | /* Enable auto-painting of the overlay colorkey */ | ||
274 | { | ||
275 | static const char *attr[] = { "XV_AUTOPAINT_COLORKEY", "XV_AUTOPAINT_COLOURKEY" }; | ||
276 | unsigned int i; | ||
277 | |||
278 | SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, True); | ||
279 | X_handler = XSetErrorHandler(xv_errhandler); | ||
280 | for ( i=0; i < sizeof(attr)/(sizeof attr[0]); ++i ) { | ||
281 | Atom a; | ||
282 | |||
283 | xv_error = False; | ||
284 | a = XInternAtom(GFX_Display, attr[i], True); | ||
285 | if ( a != None ) { | ||
286 | SDL_NAME(XvSetPortAttribute)(GFX_Display, xv_port, a, 1); | ||
287 | XSync(GFX_Display, True); | ||
288 | if ( ! xv_error ) { | ||
289 | break; | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | XSetErrorHandler(X_handler); | ||
294 | SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, False); | ||
295 | } | ||
296 | |||
297 | /* Create the overlay structure */ | ||
298 | overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay); | ||
299 | if ( overlay == NULL ) { | ||
300 | SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime); | ||
301 | SDL_OutOfMemory(); | ||
302 | return(NULL); | ||
303 | } | ||
304 | SDL_memset(overlay, 0, (sizeof *overlay)); | ||
305 | |||
306 | /* Fill in the basic members */ | ||
307 | overlay->format = format; | ||
308 | overlay->w = width; | ||
309 | overlay->h = height; | ||
310 | |||
311 | /* Set up the YUV surface function structure */ | ||
312 | overlay->hwfuncs = &x11_yuvfuncs; | ||
313 | overlay->hw_overlay = 1; | ||
314 | |||
315 | /* Create the pixel data and lookup tables */ | ||
316 | hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata); | ||
317 | overlay->hwdata = hwdata; | ||
318 | if ( hwdata == NULL ) { | ||
319 | SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime); | ||
320 | SDL_OutOfMemory(); | ||
321 | SDL_FreeYUVOverlay(overlay); | ||
322 | return(NULL); | ||
323 | } | ||
324 | hwdata->port = xv_port; | ||
325 | #ifndef NO_SHARED_MEMORY | ||
326 | yuvshm = &hwdata->yuvshm; | ||
327 | SDL_memset(yuvshm, 0, sizeof(*yuvshm)); | ||
328 | hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format, | ||
329 | 0, width, height, yuvshm); | ||
330 | #ifdef PITCH_WORKAROUND | ||
331 | if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) { | ||
332 | /* Ajust overlay width according to pitch */ | ||
333 | width = hwdata->image->pitches[0] / bpp; | ||
334 | XFree(hwdata->image); | ||
335 | hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format, | ||
336 | 0, width, height, yuvshm); | ||
337 | } | ||
338 | #endif /* PITCH_WORKAROUND */ | ||
339 | hwdata->yuv_use_mitshm = (hwdata->image != NULL); | ||
340 | if ( hwdata->yuv_use_mitshm ) { | ||
341 | yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size, | ||
342 | IPC_CREAT | 0777); | ||
343 | if ( yuvshm->shmid >= 0 ) { | ||
344 | yuvshm->shmaddr = (char *)shmat(yuvshm->shmid, 0, 0); | ||
345 | yuvshm->readOnly = False; | ||
346 | if ( yuvshm->shmaddr != (char *)-1 ) { | ||
347 | shm_error = False; | ||
348 | X_handler = XSetErrorHandler(shm_errhandler); | ||
349 | XShmAttach(GFX_Display, yuvshm); | ||
350 | XSync(GFX_Display, True); | ||
351 | XSetErrorHandler(X_handler); | ||
352 | if ( shm_error ) | ||
353 | shmdt(yuvshm->shmaddr); | ||
354 | } else { | ||
355 | shm_error = True; | ||
356 | } | ||
357 | shmctl(yuvshm->shmid, IPC_RMID, NULL); | ||
358 | } else { | ||
359 | shm_error = True; | ||
360 | } | ||
361 | if ( shm_error ) { | ||
362 | XFree(hwdata->image); | ||
363 | hwdata->yuv_use_mitshm = 0; | ||
364 | } else { | ||
365 | hwdata->image->data = yuvshm->shmaddr; | ||
366 | } | ||
367 | } | ||
368 | if ( !hwdata->yuv_use_mitshm ) | ||
369 | #endif /* NO_SHARED_MEMORY */ | ||
370 | { | ||
371 | hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format, | ||
372 | 0, width, height); | ||
373 | |||
374 | #ifdef PITCH_WORKAROUND | ||
375 | if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) { | ||
376 | /* Ajust overlay width according to pitch */ | ||
377 | XFree(hwdata->image); | ||
378 | width = hwdata->image->pitches[0] / bpp; | ||
379 | hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format, | ||
380 | 0, width, height); | ||
381 | } | ||
382 | #endif /* PITCH_WORKAROUND */ | ||
383 | if ( hwdata->image == NULL ) { | ||
384 | SDL_SetError("Couldn't create XVideo image"); | ||
385 | SDL_FreeYUVOverlay(overlay); | ||
386 | return(NULL); | ||
387 | } | ||
388 | hwdata->image->data = SDL_malloc(hwdata->image->data_size); | ||
389 | if ( hwdata->image->data == NULL ) { | ||
390 | SDL_OutOfMemory(); | ||
391 | SDL_FreeYUVOverlay(overlay); | ||
392 | return(NULL); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | /* Find the pitch and offset values for the overlay */ | ||
397 | overlay->planes = hwdata->image->num_planes; | ||
398 | overlay->pitches = (Uint16 *)SDL_malloc(overlay->planes * sizeof(Uint16)); | ||
399 | overlay->pixels = (Uint8 **)SDL_malloc(overlay->planes * sizeof(Uint8 *)); | ||
400 | if ( !overlay->pitches || !overlay->pixels ) { | ||
401 | SDL_OutOfMemory(); | ||
402 | SDL_FreeYUVOverlay(overlay); | ||
403 | return(NULL); | ||
404 | } | ||
405 | for ( i=0; i<overlay->planes; ++i ) { | ||
406 | overlay->pitches[i] = hwdata->image->pitches[i]; | ||
407 | overlay->pixels[i] = (Uint8 *)hwdata->image->data + | ||
408 | hwdata->image->offsets[i]; | ||
409 | } | ||
410 | |||
411 | #ifdef XFREE86_REFRESH_HACK | ||
412 | /* Work around an XFree86 X server bug (?) | ||
413 | We can't perform normal updates in windows that have video | ||
414 | being output to them. See SDL_x11image.c for more details. | ||
415 | */ | ||
416 | X11_DisableAutoRefresh(this); | ||
417 | #endif | ||
418 | |||
419 | #ifdef INTEL_XV_BADALLOC_WORKAROUND | ||
420 | /* HACK, GRRR sometimes (i810) creating the overlay succeeds, but the | ||
421 | first call to XvShm[Put]Image to a mapped window fails with: | ||
422 | "BadAlloc (insufficient resources for operation)". This happens with | ||
423 | certain formats when the XvImage is too large to the i810's liking. | ||
424 | |||
425 | We work around this by doing a test XvShm[Put]Image with a black | ||
426 | Xv image, this may cause some flashing, so only do this check if we | ||
427 | are running on an intel Xv-adapter. */ | ||
428 | if (intel_adapter) | ||
429 | { | ||
430 | xv_error = False; | ||
431 | X_handler = XSetErrorHandler(intel_errhandler); | ||
432 | |||
433 | X11_ClearYUVOverlay(overlay); | ||
434 | |||
435 | /* We set the destination height and width to 1 pixel to avoid | ||
436 | putting a large black rectangle over the screen, thus | ||
437 | strongly reducing possible flashing. */ | ||
438 | #ifndef NO_SHARED_MEMORY | ||
439 | if ( hwdata->yuv_use_mitshm ) { | ||
440 | SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, | ||
441 | SDL_Window, SDL_GC, | ||
442 | hwdata->image, | ||
443 | 0, 0, overlay->w, overlay->h, | ||
444 | 0, 0, 1, 1, False); | ||
445 | } | ||
446 | else | ||
447 | #endif | ||
448 | { | ||
449 | SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, | ||
450 | SDL_Window, SDL_GC, | ||
451 | hwdata->image, | ||
452 | 0, 0, overlay->w, overlay->h, | ||
453 | 0, 0, 1, 1); | ||
454 | } | ||
455 | XSync(GFX_Display, False); | ||
456 | XSetErrorHandler(X_handler); | ||
457 | |||
458 | if (xv_error) | ||
459 | { | ||
460 | X11_FreeYUVOverlay(this, overlay); | ||
461 | return NULL; | ||
462 | } | ||
463 | /* Repair the (1 pixel worth of) damage we've just done */ | ||
464 | X11_RefreshDisplay(this); | ||
465 | } | ||
466 | #endif | ||
467 | |||
468 | /* We're all done.. */ | ||
469 | return(overlay); | ||
470 | } | ||
471 | |||
472 | int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay) | ||
473 | { | ||
474 | return(0); | ||
475 | } | ||
476 | |||
477 | void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) | ||
478 | { | ||
479 | return; | ||
480 | } | ||
481 | |||
482 | int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) | ||
483 | { | ||
484 | struct private_yuvhwdata *hwdata; | ||
485 | |||
486 | hwdata = overlay->hwdata; | ||
487 | |||
488 | #ifndef NO_SHARED_MEMORY | ||
489 | if ( hwdata->yuv_use_mitshm ) { | ||
490 | SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC, | ||
491 | hwdata->image, | ||
492 | src->x, src->y, src->w, src->h, | ||
493 | dst->x, dst->y, dst->w, dst->h, False); | ||
494 | } | ||
495 | else | ||
496 | #endif | ||
497 | { | ||
498 | SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC, | ||
499 | hwdata->image, | ||
500 | src->x, src->y, src->w, src->h, | ||
501 | dst->x, dst->y, dst->w, dst->h); | ||
502 | } | ||
503 | XSync(GFX_Display, False); | ||
504 | return(0); | ||
505 | } | ||
506 | |||
507 | void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) | ||
508 | { | ||
509 | struct private_yuvhwdata *hwdata; | ||
510 | |||
511 | hwdata = overlay->hwdata; | ||
512 | if ( hwdata ) { | ||
513 | SDL_NAME(XvUngrabPort)(GFX_Display, hwdata->port, CurrentTime); | ||
514 | #ifndef NO_SHARED_MEMORY | ||
515 | if ( hwdata->yuv_use_mitshm ) { | ||
516 | XShmDetach(GFX_Display, &hwdata->yuvshm); | ||
517 | shmdt(hwdata->yuvshm.shmaddr); | ||
518 | } | ||
519 | #endif | ||
520 | if ( hwdata->image ) { | ||
521 | XFree(hwdata->image); | ||
522 | } | ||
523 | SDL_free(hwdata); | ||
524 | } | ||
525 | if ( overlay->pitches ) { | ||
526 | SDL_free(overlay->pitches); | ||
527 | overlay->pitches = NULL; | ||
528 | } | ||
529 | if ( overlay->pixels ) { | ||
530 | SDL_free(overlay->pixels); | ||
531 | overlay->pixels = NULL; | ||
532 | } | ||
533 | #ifdef XFREE86_REFRESH_HACK | ||
534 | X11_EnableAutoRefresh(this); | ||
535 | #endif | ||
536 | } | ||
537 | |||
538 | #endif /* SDL_VIDEO_DRIVER_X11_XV */ | ||
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11yuv_c.h b/apps/plugins/sdl/src/video/x11/SDL_x11yuv_c.h deleted file mode 100644 index d297683c24..0000000000 --- a/apps/plugins/sdl/src/video/x11/SDL_x11yuv_c.h +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* This is the XFree86 Xv extension implementation of YUV video overlays */ | ||
25 | |||
26 | #include "SDL_video.h" | ||
27 | #include "SDL_x11video.h" | ||
28 | |||
29 | #if SDL_VIDEO_DRIVER_X11_XV | ||
30 | |||
31 | extern SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); | ||
32 | |||
33 | extern int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay); | ||
34 | |||
35 | extern void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay); | ||
36 | |||
37 | extern int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst); | ||
38 | |||
39 | extern void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay); | ||
40 | |||
41 | #endif /* SDL_VIDEO_DRIVER_X11_XV */ | ||