summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/src/video/x11
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/src/video/x11')
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11dga.c90
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11dga_c.h33
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11dyn.c222
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11dyn.h93
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11events.c1414
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11events_c.h34
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11gamma.c142
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11gamma_c.h32
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11gl.c577
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11gl_c.h99
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11image.c316
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11image_c.h38
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11modes.c1143
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11modes_c.h43
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11mouse.c288
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11mouse_c.h33
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11sym.h201
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11video.c1571
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11video.h214
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11wm.c434
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11wm_c.h34
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11yuv.c538
-rw-r--r--apps/plugins/sdl/src/video/x11/SDL_x11yuv_c.h41
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 */
33int dga_event, dga_error = -1;
34
35void 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! */
73void 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
82void 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
31extern void X11_EnableDGAMouse(_THIS);
32extern void X11_CheckDGAMouse(_THIS);
33extern 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
37typedef 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
56static 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
64static 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
103XIC (*pXCreateIC)(XIM,...) = NULL;
104char *(*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
115static 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
130static int x11_load_refcount = 0;
131
132void 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. */
164int 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
63extern "C" {
64#endif
65
66/* evil function signatures... */
67typedef Bool (*SDL_X11_XESetWireToEventRetType)(Display*,XEvent*,xEvent*);
68typedef int (*SDL_X11_XSynchronizeRetType)(Display*);
69typedef Status (*SDL_X11_XESetEventToWireRetType)(Display*,XEvent*,xEvent*);
70
71int SDL_X11_LoadSymbols(void);
72void SDL_X11_UnloadSymbols(void);
73
74/* That's really annoying...make this a function pointer no matter what. */
75#ifdef X_HAVE_UTF8_STRING
76extern XIC (*pXCreateIC)(XIM,...);
77extern 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 */
56static SDLKey ODD_keymap[256];
57static SDLKey MISC_keymap[256];
58SDLKey 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*/
64int X11_PendingConfigureNotifyWidth = -1;
65int X11_PendingConfigureNotifyHeight = -1;
66
67#ifdef X_HAVE_UTF8_STRING
68Uint32 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
234static 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 */
308static 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
333static __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
394static 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
426printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y);
427if ( xevent.xcrossing.mode == NotifyGrab )
428printf("Mode: NotifyGrab\n");
429if ( xevent.xcrossing.mode == NotifyUngrab )
430printf("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
444printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y);
445if ( xevent.xcrossing.mode == NotifyGrab )
446printf("Mode: NotifyGrab\n");
447if ( xevent.xcrossing.mode == NotifyUngrab )
448printf("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
467printf("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
485printf("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
512printf("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
564printf("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
765printf("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
781printf("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
798printf("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
826printf("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
878printf("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
888printf("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 */
906int 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
932void 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
986void 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 */
1119SDLKey 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 */
1198static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask;
1199static unsigned num_mask, mode_switch_mask;
1200
1201static 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 */
1249Uint16 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 */
1310void 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
1410void 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 */
27extern void X11_InitOSKeymap(_THIS);
28extern void X11_PumpEvents(_THIS);
29extern void X11_SetKeyboardState(Display *display, const char *key_vec);
30
31/* Variables to be exported */
32extern int X11_PendingConfigureNotifyWidth;
33extern 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
33static 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}
83int 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
94static 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}
110int 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
121void 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}
131void 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
27extern int X11_SetVidModeGamma(_THIS, float red, float green, float blue);
28extern int X11_GetVidModeGamma(_THIS, float *red, float *green, float *blue);
29extern void X11_SaveVidModeGamma(_THIS);
30extern 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
64static 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
102XVisualInfo *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
229int 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
261int 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
316void 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 */
335int 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. */
356int 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
445void 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
464void 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 */
490int 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
569void *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
31struct 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 */
87extern XVisualInfo *X11_GL_GetVisual(_THIS);
88extern int X11_GL_CreateWindow(_THIS, int w, int h);
89extern int X11_GL_CreateContext(_THIS);
90extern void X11_GL_Shutdown(_THIS);
91#if SDL_VIDEO_OPENGL_GLX
92extern int X11_GL_MakeCurrent(_THIS);
93extern int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
94extern void X11_GL_SwapBuffers(_THIS);
95extern int X11_GL_LoadLibrary(_THIS, const char* path);
96extern void *X11_GL_GetProcAddress(_THIS, const char* proc);
97#endif
98extern 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 */
34static int shm_error;
35static int (*X_handler)(Display *, XErrorEvent *) = NULL;
36static 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
45static 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 */
81static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
82static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects);
83
84int 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
125error:
126 SDL_SetError("Couldn't create XImage");
127 return 1;
128}
129
130void 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 */
149static 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
181int 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 */
206int X11_AllocHWSurface(_THIS, SDL_Surface *surface)
207{
208 return(-1);
209}
210void X11_FreeHWSurface(_THIS, SDL_Surface *surface)
211{
212 return;
213}
214
215int 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}
223void X11_UnlockHWSurface(_THIS, SDL_Surface *surface)
224{
225 return;
226}
227
228int X11_FlipHWSurface(_THIS, SDL_Surface *surface)
229{
230 return(0);
231}
232
233static 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
253static 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*/
282static int enable_autorefresh = 1;
283
284void X11_DisableAutoRefresh(_THIS)
285{
286 --enable_autorefresh;
287}
288
289void X11_EnableAutoRefresh(_THIS)
290{
291 ++enable_autorefresh;
292}
293
294void 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
26extern int X11_SetupImage(_THIS, SDL_Surface *screen);
27extern void X11_DestroyImage(_THIS, SDL_Surface *screen);
28extern int X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags);
29
30extern int X11_AllocHWSurface(_THIS, SDL_Surface *surface);
31extern void X11_FreeHWSurface(_THIS, SDL_Surface *surface);
32extern int X11_LockHWSurface(_THIS, SDL_Surface *surface);
33extern void X11_UnlockHWSurface(_THIS, SDL_Surface *surface);
34extern int X11_FlipHWSurface(_THIS, SDL_Surface *surface);
35
36extern void X11_DisableAutoRefresh(_THIS);
37extern void X11_EnableAutoRefresh(_THIS);
38extern 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
41static 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
53Bool 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
78static 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
87static 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
105static 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
116static void get_real_resolution(_THIS, int* w, int* h);
117
118static 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
250static 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 */
319void 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 */
328void 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
336static 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
341static 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}
353static 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}
364static 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 */
385int vm_event, vm_error = -1;
386
387#if SDL_VIDEO_DRIVER_X11_XINERAMA
388static 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
411static 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
442static 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
488static 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
509int 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
888int 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
897SDL_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
910void 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
931int 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
975void 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
984int 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
1083int 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
35extern int X11_GetVideoModes(_THIS);
36extern SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
37extern void X11_FreeVideoModes(_THIS);
38extern int X11_ResizeFullScreen(_THIS);
39extern void X11_WaitMapped(_THIS, Window win);
40extern void X11_WaitUnmapped(_THIS, Window win);
41extern void X11_QueueEnterFullScreen(_THIS);
42extern int X11_EnterFullScreen(_THIS);
43extern 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 */
35struct WMcursor {
36 Cursor x_cursor;
37};
38
39
40void 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
51WMcursor *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
146int 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
170void 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*/
192static 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 */
227void 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}
283void 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 */
27extern void X11_FreeWMCursor(_THIS, WMcursor *cursor);
28extern WMcursor *X11_CreateWMCursor(_THIS,
29 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
30extern int X11_ShowWMCursor(_THIS, WMcursor *cursor);
31extern void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
32extern void X11_CheckMouseModeNoLock(_THIS);
33extern 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
23SDL_X11_MODULE(BASEXLIB)
24SDL_X11_SYM(XClassHint*,XAllocClassHint,(void),(),return)
25SDL_X11_SYM(Status,XAllocColor,(Display* a,Colormap b,XColor* c),(a,b,c),return)
26SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return)
27SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return)
28SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return)
29SDL_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)
30SDL_X11_SYM(int,XChangeWindowAttributes,(Display* a,Window b,unsigned long c,XSetWindowAttributes* d),(a,b,c,d),return)
31SDL_X11_SYM(Bool,XCheckTypedEvent,(Display* a,int b,XEvent* c),(a,b,c),return)
32SDL_X11_SYM(int,XClearWindow,(Display* a,Window b),(a,b),return)
33SDL_X11_SYM(int,XCloseDisplay,(Display* a),(a),return)
34SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return)
35SDL_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)
36SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return)
37SDL_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)
38SDL_X11_SYM(Pixmap,XCreatePixmap,(Display* a,Drawable b,unsigned int c,unsigned int d,unsigned int e),(a,b,c,d,e),return)
39SDL_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)
40SDL_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)
41SDL_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)
42SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c),(a,b,c),return)
43SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c),(a,b,c),return)
44SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b),(a,b),return)
45SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a),(a),return)
46SDL_X11_SYM(int,XEventsQueued,(Display* a,int b),(a,b),return)
47SDL_X11_SYM(Bool,XFilterEvent,(XEvent *event, Window w),(event,w),return)
48SDL_X11_SYM(int,XFlush,(Display* a),(a),return)
49SDL_X11_SYM(int,XFree,(void*a),(a),return)
50SDL_X11_SYM(int,XFreeColormap,(Display* a,Colormap b),(a,b),return)
51SDL_X11_SYM(int,XFreeColors,(Display* a,Colormap b,unsigned long* c,int d,unsigned long e),(a,b,c,d,e),return)
52SDL_X11_SYM(int,XFreeCursor,(Display* a,Cursor b),(a,b),return)
53SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
54SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
55SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
56SDL_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)
57SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return)
58SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return)
59SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return)
60SDL_X11_SYM(XWMHints*,XGetWMHints,(Display* a,Window b),(a,b),return)
61SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return)
62SDL_X11_SYM(int,XGrabKeyboard,(Display* a,Window b,Bool c,int d,int e,Time f),(a,b,c,d,e,f),return)
63SDL_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)
64SDL_X11_SYM(Status,XIconifyWindow,(Display* a,Window b,int c),(a,b,c),return)
65SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return)
66SDL_X11_SYM(KeyCode,XKeysymToKeycode,(Display* a,KeySym b),(a,b),return)
67SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return)
68SDL_X11_SYM(XPixmapFormatValues*,XListPixmapFormats,(Display* a,int* b),(a,b),return)
69SDL_X11_SYM(int,XLookupString,(XKeyEvent* a,char* b,int c,KeySym* d,XComposeStatus* e),(a,b,c,d,e),return)
70SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return)
71SDL_X11_SYM(int,XMapWindow,(Display* a,Window b),(a,b),return)
72SDL_X11_SYM(int,XMaskEvent,(Display* a,long b,XEvent* c),(a,b,c),return)
73SDL_X11_SYM(Status,XMatchVisualInfo,(Display* a,int b,int c,int d,XVisualInfo* e),(a,b,c,d,e),return)
74SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return)
75SDL_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)
76SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return)
77SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return)
78SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return)
79SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return)
80SDL_X11_SYM(int,XPending,(Display* a),(a),return)
81SDL_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)
82SDL_X11_SYM(int,XQueryColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return)
83SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return)
84SDL_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)
85SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return)
86SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return)
87SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return)
88SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return)
89SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return)
90SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return)
91SDL_X11_SYM(int,XSetClassHint,(Display* a,Window b,XClassHint* c),(a,b,c),return)
92SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return)
93SDL_X11_SYM(XIOErrorHandler,XSetIOErrorHandler,(XIOErrorHandler a),(a),return)
94SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return)
95SDL_X11_SYM(int,XSetWMHints,(Display* a,Window b,XWMHints* c),(a,b,c),return)
96SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),)
97SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),)
98SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return)
99SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return)
100SDL_X11_SYM(int,XSetWindowBackgroundPixmap,(Display* a,Window b,Pixmap c),(a,b,c),return)
101SDL_X11_SYM(int,XSetWindowColormap,(Display* a,Window b,Colormap c),(a,b,c),return)
102SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return)
103SDL_X11_SYM(Status,XStringListToTextProperty,(char** a,int b,XTextProperty* c),(a,b,c),return)
104SDL_X11_SYM(int,XSync,(Display* a,Bool b),(a,b),return)
105SDL_X11_SYM(int,XUngrabKeyboard,(Display* a,Time b),(a,b),return)
106SDL_X11_SYM(int,XUngrabPointer,(Display* a,Time b),(a,b),return)
107SDL_X11_SYM(int,XUnmapWindow,(Display* a,Window b),(a,b),return)
108SDL_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)
109SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return)
110SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return)
111SDL_X11_SYM(XExtensionInfo*,XextCreateExtension,(void),(),return)
112SDL_X11_SYM(void,XextDestroyExtension,(XExtensionInfo* a),(a),)
113SDL_X11_SYM(XExtDisplayInfo*,XextFindDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
114SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
115SDL_X11_SYM(Bool,XQueryExtension,(Display* a,_Xconst char* b,int* c,int* d,int* e),(a,b,c,d,e),return)
116SDL_X11_SYM(char *,XDisplayString,(Display* a),(a),return)
117SDL_X11_SYM(int,XGetErrorText,(Display* a,int b,char* c,int d),(a,b,c,d),return)
118SDL_X11_SYM(void,_XEatData,(Display* a,unsigned long b),(a,b),)
119SDL_X11_SYM(void,_XFlush,(Display* a),(a),)
120SDL_X11_SYM(void,_XFlushGCCache,(Display* a,GC b),(a,b),)
121SDL_X11_SYM(int,_XRead,(Display* a,char* b,long c),(a,b,c),return)
122SDL_X11_SYM(void,_XReadPad,(Display* a,char* b,long c),(a,b,c),)
123SDL_X11_SYM(void,_XSend,(Display* a,_Xconst char* b,long c),(a,b,c),)
124SDL_X11_SYM(Status,_XReply,(Display* a,xReply* b,int c,Bool d),(a,b,c,d),return)
125SDL_X11_SYM(unsigned long,_XSetLastRequestRead,(Display* a,xGenericReply* b),(a,b),return)
126SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),return)
127SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,SDL_X11_XESetWireToEventRetType c),(a,b,c),return)
128SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
129SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return)
130
131#if NeedWidePrototypes
132SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
133#else
134SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,KeyCode b,int c),(a,b,c),return)
135#endif
136
137#ifdef X_HAVE_UTF8_STRING
138SDL_X11_MODULE(UTF8)
139SDL_X11_SYM(int,Xutf8TextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return)
140SDL_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! */
142SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),)
143SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),)
144SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),)
145/*SDL_X11_SYM(char*,XGetICValues,(XIC a, ...),return)*/
146SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return)
147SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return)
148SDL_X11_SYM(char*,XSetLocaleModifiers,(_Xconst char* a),(a),return)
149SDL_X11_SYM(int,XRefreshKeyboardMapping,(XMappingEvent* a),(a),return)
150SDL_X11_SYM(Display*,XDisplayOfIM,(XIM a),(a),return)
151#endif
152
153#ifndef NO_SHARED_MEMORY
154SDL_X11_MODULE(SHM)
155SDL_X11_SYM(Status,XShmAttach,(Display* a,XShmSegmentInfo* b),(a,b),return)
156SDL_X11_SYM(Status,XShmDetach,(Display* a,XShmSegmentInfo* b),(a,b),return)
157SDL_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)
158SDL_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)
159SDL_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
167SDL_X11_MODULE(IO_32BIT)
168SDL_X11_SYM(int,_XData32,(Display *dpy,register long *data,unsigned len),(dpy,data,len),return)
169SDL_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 */
175SDL_X11_MODULE(XGETREQUEST)
176SDL_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__)
182SDL_X11_MODULE(OSF_ENTRY_POINTS)
183SDL_X11_SYM(void,_SmtBufferOverflow,(Display *dpy,register smtDisplayPtr p),(dpy,p),)
184SDL_X11_SYM(void,_SmtIpError,(Display *dpy,register smtDisplayPtr p, int i),(dpy,p,i),)
185SDL_X11_SYM(int,ipAllocateData,(ChannelPtr a, IPCard b, IPDataPtr * c),(a,b,c),return)
186SDL_X11_SYM(int,ipUnallocateAndSendData,(ChannelPtr a, IPCard b),(a,b),return)
187#endif
188
189/* Xrandr support. */
190#if SDL_VIDEO_DRIVER_X11_XRANDR
191SDL_X11_MODULE(XRANDR)
192SDL_X11_SYM(Status,XRRQueryVersion,(Display *dpy,int *major_versionp,int *minor_versionp),(dpy,major_versionp,minor_versionp),return)
193SDL_X11_SYM(XRRScreenConfiguration *,XRRGetScreenInfo,(Display *dpy,Drawable draw),(dpy,draw),return)
194SDL_X11_SYM(SizeID,XRRConfigCurrentConfiguration,(XRRScreenConfiguration *config,Rotation *rotation),(config,rotation),return)
195SDL_X11_SYM(XRRScreenSize *,XRRConfigSizes,(XRRScreenConfiguration *config, int *nsizes),(config,nsizes),return)
196SDL_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)
197SDL_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 */
62static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat);
63static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
64static int X11_ToggleFullScreen(_THIS, int on);
65static void X11_UpdateMouse(_THIS);
66static int X11_SetColors(_THIS, int firstcolor, int ncolors,
67 SDL_Color *colors);
68static int X11_SetGammaRamp(_THIS, Uint16 *ramp);
69static void X11_VideoQuit(_THIS);
70
71
72/* X11 driver bootstrap functions */
73
74static 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
87static 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
101static 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
182VideoBootStrap X11_bootstrap = {
183 "x11", "X Window System",
184 X11_Available, X11_CreateDevice
185};
186
187/* Normal X11 error handler routine */
188static int (*X_handler)(Display *, XErrorEvent *) = NULL;
189static 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));
211printf("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));
226printf("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 */
237static int (*XIO_handler)(Display *) = NULL;
238static 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
252static int (*Xext_handler)(Display *, _Xconst char *, _Xconst char *) = NULL;
253static 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 */
275static 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 */
319static 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
575static 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
719static 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
766static 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
786static 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
906static 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
1123static 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
1152SDL_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
1242static 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 */
1275static 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, &current_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
1305static 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
1367int 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
1458int 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*/
1487void 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 */
56struct 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
36static 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
44void 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
244void 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
309void 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 */
317int 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
328SDL_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
381SDL_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*/
393static void lock_display(void)
394{
395 SDL_Lock_EventThread();
396}
397static 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>
406int 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 */
27extern void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon);
28extern void X11_SetCaption(_THIS, const char *title, const char *icon);
29extern void X11_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask);
30extern int X11_IconifyWindow(_THIS);
31extern SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode);
32extern SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode);
33extern 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 */
55static struct private_yuvhwfuncs x11_yuvfuncs = {
56 X11_LockYUVOverlay,
57 X11_UnlockYUVOverlay,
58 X11_DisplayYUVOverlay,
59 X11_FreeYUVOverlay
60};
61
62struct 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
72static int (*X_handler)(Display *, XErrorEvent *) = NULL;
73
74#ifndef NO_SHARED_MEMORY
75/* Shared memory error handler routine */
76static int shm_error;
77static 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
87static int xv_error;
88static 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
98static 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
107static 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
160SDL_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
472int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
473{
474 return(0);
475}
476
477void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
478{
479 return;
480}
481
482int 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
507void 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
31extern SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
32
33extern int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
34
35extern void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
36
37extern int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
38
39extern void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
40
41#endif /* SDL_VIDEO_DRIVER_X11_XV */