comparison src/video/x11/SDL_x11video.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 0e44c6f90b95
children
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
53 #include "SDL_x11gl_c.h" 53 #include "SDL_x11gl_c.h"
54 #include "SDL_x11gamma_c.h" 54 #include "SDL_x11gamma_c.h"
55 #include "../blank_cursor.h" 55 #include "../blank_cursor.h"
56 56
57 /* Initialization/Query functions */ 57 /* Initialization/Query functions */
58 static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat); 58 static int X11_VideoInit(_THIS);
59 static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 59 static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface * current,
60 const SDL_DisplayMode * mode,
61 Uint32 flags);
60 static int X11_ToggleFullScreen(_THIS, int on); 62 static int X11_ToggleFullScreen(_THIS, int on);
61 static void X11_UpdateMouse(_THIS); 63 static void X11_UpdateMouse(_THIS);
62 static int X11_SetColors(_THIS, int firstcolor, int ncolors, 64 static int X11_SetColors(_THIS, int firstcolor, int ncolors,
63 SDL_Color *colors); 65 SDL_Color * colors);
64 static int X11_SetGammaRamp(_THIS, Uint16 *ramp); 66 static int X11_SetGammaRamp(_THIS, Uint16 * ramp);
65 static void X11_VideoQuit(_THIS); 67 static void X11_VideoQuit(_THIS);
66 68
67 69
68 /* X11 driver bootstrap functions */ 70 /* X11 driver bootstrap functions */
69 71
70 static int X11_Available(void) 72 static int
71 { 73 X11_Available(void)
72 Display *display = NULL; 74 {
73 if ( SDL_X11_LoadSymbols() ) { 75 Display *display = NULL;
74 display = XOpenDisplay(NULL); 76 if (SDL_X11_LoadSymbols()) {
75 if ( display != NULL ) { 77 display = XOpenDisplay(NULL);
76 XCloseDisplay(display); 78 if (display != NULL) {
77 } 79 XCloseDisplay(display);
78 SDL_X11_UnloadSymbols(); 80 }
79 } 81 SDL_X11_UnloadSymbols();
80 return(display != NULL); 82 }
81 } 83 return (display != NULL);
82 84 }
83 static void X11_DeleteDevice(SDL_VideoDevice *device) 85
84 { 86 static void
85 if ( device ) { 87 X11_DeleteDevice(SDL_VideoDevice * device)
86 if ( device->hidden ) { 88 {
87 SDL_free(device->hidden); 89 if (device) {
88 } 90 if (device->hidden) {
89 if ( device->gl_data ) { 91 SDL_free(device->hidden);
90 SDL_free(device->gl_data); 92 }
91 } 93 if (device->gl_data) {
92 SDL_free(device); 94 SDL_free(device->gl_data);
93 SDL_X11_UnloadSymbols(); 95 }
94 } 96 SDL_free(device);
95 } 97 SDL_X11_UnloadSymbols();
96 98 }
97 static SDL_VideoDevice *X11_CreateDevice(int devindex) 99 }
98 { 100
99 SDL_VideoDevice *device = NULL; 101 static SDL_VideoDevice *
100 102 X11_CreateDevice(int devindex)
101 if ( SDL_X11_LoadSymbols() ) { 103 {
102 /* Initialize all variables that we clean on shutdown */ 104 SDL_VideoDevice *device = NULL;
103 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); 105
104 if ( device ) { 106 if (SDL_X11_LoadSymbols()) {
105 SDL_memset(device, 0, (sizeof *device)); 107 /* Initialize all variables that we clean on shutdown */
106 device->hidden = (struct SDL_PrivateVideoData *) 108 device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
107 SDL_malloc((sizeof *device->hidden)); 109 if (device) {
108 device->gl_data = (struct SDL_PrivateGLData *) 110 SDL_memset(device, 0, (sizeof *device));
109 SDL_malloc((sizeof *device->gl_data)); 111 device->hidden = (struct SDL_PrivateVideoData *)
110 } 112 SDL_malloc((sizeof *device->hidden));
111 if ( (device == NULL) || (device->hidden == NULL) || 113 device->gl_data = (struct SDL_PrivateGLData *)
112 (device->gl_data == NULL) ) { 114 SDL_malloc((sizeof *device->gl_data));
113 SDL_OutOfMemory(); 115 }
114 X11_DeleteDevice(device); /* calls SDL_X11_UnloadSymbols(). */ 116 if ((device == NULL) || (device->hidden == NULL) ||
115 return(0); 117 (device->gl_data == NULL)) {
116 } 118 SDL_OutOfMemory();
117 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); 119 X11_DeleteDevice(device); /* calls SDL_X11_UnloadSymbols(). */
118 SDL_memset(device->gl_data, 0, (sizeof *device->gl_data)); 120 return (0);
119 121 }
120 /* Set the driver flags */ 122 SDL_memset(device->hidden, 0, (sizeof *device->hidden));
121 device->handles_any_size = 1; 123 SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
122 124
123 /* Set the function pointers */ 125 /* Set the driver flags */
124 device->VideoInit = X11_VideoInit; 126 device->handles_any_size = 1;
125 device->ListModes = X11_ListModes; 127
126 device->SetVideoMode = X11_SetVideoMode; 128 /* Set the function pointers */
127 device->ToggleFullScreen = X11_ToggleFullScreen; 129 device->VideoInit = X11_VideoInit;
128 device->UpdateMouse = X11_UpdateMouse; 130 device->SetVideoMode = X11_SetVideoMode;
131 device->ToggleFullScreen = X11_ToggleFullScreen;
132 device->UpdateMouse = X11_UpdateMouse;
129 #if SDL_VIDEO_DRIVER_X11_XV 133 #if SDL_VIDEO_DRIVER_X11_XV
130 device->CreateYUVOverlay = X11_CreateYUVOverlay; 134 device->CreateYUVOverlay = X11_CreateYUVOverlay;
131 #endif 135 #endif
132 device->SetColors = X11_SetColors; 136 device->SetColors = X11_SetColors;
133 device->UpdateRects = NULL; 137 device->UpdateRects = NULL;
134 device->VideoQuit = X11_VideoQuit; 138 device->VideoQuit = X11_VideoQuit;
135 device->AllocHWSurface = X11_AllocHWSurface; 139 device->AllocHWSurface = X11_AllocHWSurface;
136 device->CheckHWBlit = NULL; 140 device->CheckHWBlit = NULL;
137 device->FillHWRect = NULL; 141 device->FillHWRect = NULL;
138 device->SetHWColorKey = NULL; 142 device->SetHWColorKey = NULL;
139 device->SetHWAlpha = NULL; 143 device->SetHWAlpha = NULL;
140 device->LockHWSurface = X11_LockHWSurface; 144 device->LockHWSurface = X11_LockHWSurface;
141 device->UnlockHWSurface = X11_UnlockHWSurface; 145 device->UnlockHWSurface = X11_UnlockHWSurface;
142 device->FlipHWSurface = X11_FlipHWSurface; 146 device->FlipHWSurface = X11_FlipHWSurface;
143 device->FreeHWSurface = X11_FreeHWSurface; 147 device->FreeHWSurface = X11_FreeHWSurface;
144 device->SetGamma = X11_SetVidModeGamma; 148 device->SetGamma = X11_SetVidModeGamma;
145 device->GetGamma = X11_GetVidModeGamma; 149 device->GetGamma = X11_GetVidModeGamma;
146 device->SetGammaRamp = X11_SetGammaRamp; 150 device->SetGammaRamp = X11_SetGammaRamp;
147 device->GetGammaRamp = NULL; 151 device->GetGammaRamp = NULL;
148 #if SDL_VIDEO_OPENGL_GLX 152 #if SDL_VIDEO_OPENGL_GLX
149 device->GL_LoadLibrary = X11_GL_LoadLibrary; 153 device->GL_LoadLibrary = X11_GL_LoadLibrary;
150 device->GL_GetProcAddress = X11_GL_GetProcAddress; 154 device->GL_GetProcAddress = X11_GL_GetProcAddress;
151 device->GL_GetAttribute = X11_GL_GetAttribute; 155 device->GL_GetAttribute = X11_GL_GetAttribute;
152 device->GL_MakeCurrent = X11_GL_MakeCurrent; 156 device->GL_MakeCurrent = X11_GL_MakeCurrent;
153 device->GL_SwapBuffers = X11_GL_SwapBuffers; 157 device->GL_SwapBuffers = X11_GL_SwapBuffers;
154 #endif 158 #endif
155 device->SetCaption = X11_SetCaption; 159 device->SetCaption = X11_SetCaption;
156 device->SetIcon = X11_SetIcon; 160 device->SetIcon = X11_SetIcon;
157 device->IconifyWindow = X11_IconifyWindow; 161 device->IconifyWindow = X11_IconifyWindow;
158 device->GrabInput = X11_GrabInput; 162 device->GrabInput = X11_GrabInput;
159 device->GetWMInfo = X11_GetWMInfo; 163 device->GetWMInfo = X11_GetWMInfo;
160 device->FreeWMCursor = X11_FreeWMCursor; 164 device->FreeWMCursor = X11_FreeWMCursor;
161 device->CreateWMCursor = X11_CreateWMCursor; 165 device->CreateWMCursor = X11_CreateWMCursor;
162 device->ShowWMCursor = X11_ShowWMCursor; 166 device->ShowWMCursor = X11_ShowWMCursor;
163 device->WarpWMCursor = X11_WarpWMCursor; 167 device->WarpWMCursor = X11_WarpWMCursor;
164 device->CheckMouseMode = X11_CheckMouseMode; 168 device->CheckMouseMode = X11_CheckMouseMode;
165 device->InitOSKeymap = X11_InitOSKeymap; 169 device->InitOSKeymap = X11_InitOSKeymap;
166 device->PumpEvents = X11_PumpEvents; 170 device->PumpEvents = X11_PumpEvents;
167 171
168 device->free = X11_DeleteDevice; 172 device->free = X11_DeleteDevice;
169 } 173 }
170 174
171 return device; 175 return device;
172 } 176 }
173 177
174 VideoBootStrap X11_bootstrap = { 178 VideoBootStrap X11_bootstrap = {
175 "x11", "X Window System", 179 "x11", "X Window System",
176 X11_Available, X11_CreateDevice 180 X11_Available, X11_CreateDevice
177 }; 181 };
178 182
179 /* Normal X11 error handler routine */ 183 /* Normal X11 error handler routine */
180 static int (*X_handler)(Display *, XErrorEvent *) = NULL; 184 static int (*X_handler) (Display *, XErrorEvent *) = NULL;
181 static int x_errhandler(Display *d, XErrorEvent *e) 185 static int
186 x_errhandler(Display * d, XErrorEvent * e)
182 { 187 {
183 #if SDL_VIDEO_DRIVER_X11_VIDMODE 188 #if SDL_VIDEO_DRIVER_X11_VIDMODE
184 extern int vm_error; 189 extern int vm_error;
185 #endif 190 #endif
186 #if SDL_VIDEO_DRIVER_X11_DGAMOUSE 191 #if SDL_VIDEO_DRIVER_X11_DGAMOUSE
187 extern int dga_error; 192 extern int dga_error;
188 #endif 193 #endif
189 194
190 #if SDL_VIDEO_DRIVER_X11_VIDMODE 195 #if SDL_VIDEO_DRIVER_X11_VIDMODE
191 /* VidMode errors are non-fatal. :) */ 196 /* VidMode errors are non-fatal. :) */
192 /* Are the errors offset by one from the error base? 197 /* Are the errors offset by one from the error base?
193 e.g. the error base is 143, the code is 148, and the 198 e.g. the error base is 143, the code is 148, and the
194 actual error is XF86VidModeExtensionDisabled (4) ? 199 actual error is XF86VidModeExtensionDisabled (4) ?
195 */ 200 */
196 if ( (vm_error >= 0) && 201 if ((vm_error >= 0) &&
197 (((e->error_code == BadRequest)&&(e->request_code == vm_error)) || 202 (((e->error_code == BadRequest) && (e->request_code == vm_error)) ||
198 ((e->error_code > vm_error) && 203 ((e->error_code > vm_error) &&
199 (e->error_code <= (vm_error+XF86VidModeNumberErrors)))) ) { 204 (e->error_code <= (vm_error + XF86VidModeNumberErrors))))) {
200 #ifdef X11_DEBUG 205 #ifdef X11_DEBUG
201 { char errmsg[1024]; 206 {
202 XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg)); 207 char errmsg[1024];
203 printf("VidMode error: %s\n", errmsg); 208 XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));
204 } 209 printf("VidMode error: %s\n", errmsg);
205 #endif 210 }
206 return(0); 211 #endif
207 } 212 return (0);
213 }
208 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ 214 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
209 215
210 #if SDL_VIDEO_DRIVER_X11_DGAMOUSE 216 #if SDL_VIDEO_DRIVER_X11_DGAMOUSE
211 /* DGA errors can be non-fatal. :) */ 217 /* DGA errors can be non-fatal. :) */
212 if ( (dga_error >= 0) && 218 if ((dga_error >= 0) &&
213 ((e->error_code > dga_error) && 219 ((e->error_code > dga_error) &&
214 (e->error_code <= (dga_error+XF86DGANumberErrors))) ) { 220 (e->error_code <= (dga_error + XF86DGANumberErrors)))) {
215 #ifdef X11_DEBUG 221 #ifdef X11_DEBUG
216 { char errmsg[1024]; 222 {
217 XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg)); 223 char errmsg[1024];
218 printf("DGA error: %s\n", errmsg); 224 XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));
219 } 225 printf("DGA error: %s\n", errmsg);
220 #endif 226 }
221 return(0); 227 #endif
222 } 228 return (0);
229 }
223 #endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */ 230 #endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */
224 231
225 return(X_handler(d,e)); 232 return (X_handler(d, e));
226 } 233 }
227 234
228 /* X11 I/O error handler routine */ 235 /* X11 I/O error handler routine */
229 static int (*XIO_handler)(Display *) = NULL; 236 static int (*XIO_handler) (Display *) = NULL;
230 static int xio_errhandler(Display *d) 237 static int
231 { 238 xio_errhandler(Display * d)
232 /* Ack! Lost X11 connection! */ 239 {
233 240 /* Ack! Lost X11 connection! */
234 /* We will crash if we try to clean up our display */ 241
235 if ( current_video->hidden->Ximage ) { 242 /* We will crash if we try to clean up our display */
236 SDL_VideoSurface->pixels = NULL; 243 if (current_video->hidden->Ximage) {
237 } 244 SDL_VideoSurface->pixels = NULL;
238 current_video->hidden->X11_Display = NULL; 245 }
239 246 current_video->hidden->X11_Display = NULL;
240 /* Continue with the standard X11 error handler */ 247
241 return(XIO_handler(d)); 248 /* Continue with the standard X11 error handler */
242 } 249 return (XIO_handler(d));
243 250 }
244 static int (*Xext_handler)(Display *, _Xconst char *, _Xconst char *) = NULL; 251
245 static int xext_errhandler(Display *d, _Xconst char *ext, _Xconst char *reason) 252 static int (*Xext_handler) (Display *, _Xconst char *, _Xconst char *) = NULL;
253 static int
254 xext_errhandler(Display * d, _Xconst char *ext, _Xconst char *reason)
246 { 255 {
247 #ifdef X11_DEBUG 256 #ifdef X11_DEBUG
248 printf("Xext error inside SDL (may be harmless):\n"); 257 printf("Xext error inside SDL (may be harmless):\n");
249 printf(" Extension \"%s\" %s on display \"%s\".\n", 258 printf(" Extension \"%s\" %s on display \"%s\".\n",
250 ext, reason, XDisplayString(d)); 259 ext, reason, XDisplayString(d));
251 #endif 260 #endif
252 261
253 if (SDL_strcmp(reason, "missing") == 0) { 262 if (SDL_strcmp(reason, "missing") == 0) {
254 /* 263 /*
255 * Since the query itself, elsewhere, can handle a missing extension 264 * Since the query itself, elsewhere, can handle a missing extension
256 * and the default behaviour in Xlib is to write to stderr, which 265 * and the default behaviour in Xlib is to write to stderr, which
257 * generates unnecessary bug reports, we just ignore these. 266 * generates unnecessary bug reports, we just ignore these.
258 */ 267 */
259 return 0; 268 return 0;
260 } 269 }
261 270
262 /* Everything else goes to the default handler... */ 271 /* Everything else goes to the default handler... */
263 return Xext_handler(d, ext, reason); 272 return Xext_handler(d, ext, reason);
264 } 273 }
265 274
266 /* Find out what class name we should use */ 275 /* Find out what class name we should use */
267 static char *get_classname(char *classname, int maxlen) 276 static char *
268 { 277 get_classname(char *classname, int maxlen)
269 char *spot; 278 {
279 char *spot;
270 #if defined(__LINUX__) || defined(__FREEBSD__) 280 #if defined(__LINUX__) || defined(__FREEBSD__)
271 char procfile[1024]; 281 char procfile[1024];
272 char linkfile[1024]; 282 char linkfile[1024];
273 int linksize; 283 int linksize;
274 #endif 284 #endif
275 285
276 /* First allow environment variable override */ 286 /* First allow environment variable override */
277 spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS"); 287 spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
278 if ( spot ) { 288 if (spot) {
279 SDL_strlcpy(classname, spot, maxlen); 289 SDL_strlcpy(classname, spot, maxlen);
280 return classname; 290 return classname;
281 } 291 }
282 292
283 /* Next look at the application's executable name */ 293 /* Next look at the application's executable name */
284 #if defined(__LINUX__) || defined(__FREEBSD__) 294 #if defined(__LINUX__) || defined(__FREEBSD__)
285 #if defined(__LINUX__) 295 #if defined(__LINUX__)
286 SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid()); 296 SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
287 #elif defined(__FREEBSD__) 297 #elif defined(__FREEBSD__)
288 SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", getpid()); 298 SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
299 getpid());
289 #else 300 #else
290 #error Where can we find the executable name? 301 #error Where can we find the executable name?
291 #endif 302 #endif
292 linksize = readlink(procfile, linkfile, sizeof(linkfile)-1); 303 linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
293 if ( linksize > 0 ) { 304 if (linksize > 0) {
294 linkfile[linksize] = '\0'; 305 linkfile[linksize] = '\0';
295 spot = SDL_strrchr(linkfile, '/'); 306 spot = SDL_strrchr(linkfile, '/');
296 if ( spot ) { 307 if (spot) {
297 SDL_strlcpy(classname, spot+1, maxlen); 308 SDL_strlcpy(classname, spot + 1, maxlen);
298 } else { 309 } else {
299 SDL_strlcpy(classname, linkfile, maxlen); 310 SDL_strlcpy(classname, linkfile, maxlen);
300 } 311 }
301 return classname; 312 return classname;
302 } 313 }
303 #endif /* __LINUX__ */ 314 #endif /* __LINUX__ */
304 315
305 /* Finally use the default we've used forever */ 316 /* Finally use the default we've used forever */
306 SDL_strlcpy(classname, "SDL_App", maxlen); 317 SDL_strlcpy(classname, "SDL_App", maxlen);
307 return classname; 318 return classname;
308 } 319 }
309 320
310 /* Create auxiliary (toplevel) windows with the current visual */ 321 /* Create auxiliary (toplevel) windows with the current visual */
311 static void create_aux_windows(_THIS) 322 static void
323 create_aux_windows(_THIS)
312 { 324 {
313 int x = 0, y = 0; 325 int x = 0, y = 0;
314 char classname[1024]; 326 char classname[1024];
315 XSetWindowAttributes xattr; 327 XSetWindowAttributes xattr;
316 XWMHints *hints; 328 XWMHints *hints;
318 330
319 /* Look up some useful Atoms */ 331 /* Look up some useful Atoms */
320 WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False); 332 WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
321 333
322 /* Don't create any extra windows if we are being managed */ 334 /* Don't create any extra windows if we are being managed */
323 if ( SDL_windowid ) { 335 if (SDL_windowid) {
324 FSwindow = 0; 336 FSwindow = 0;
325 WMwindow = SDL_strtol(SDL_windowid, NULL, 0); 337 WMwindow = SDL_strtol(SDL_windowid, NULL, 0);
326 return; 338 return;
327 } 339 }
328 340
329 if(FSwindow) 341 if (FSwindow)
330 XDestroyWindow(SDL_Display, FSwindow); 342 XDestroyWindow(SDL_Display, FSwindow);
331 343
332 #if SDL_VIDEO_DRIVER_X11_XINERAMA 344 #if SDL_VIDEO_DRIVER_X11_XINERAMA
333 if ( use_xinerama ) { 345 if (use_xinerama) {
334 x = xinerama_info.x_org; 346 x = xinerama[this->current_display].x_org;
335 y = xinerama_info.y_org; 347 y = xinerama[this->current_display].y_org;
336 } 348 }
337 #endif 349 #endif
338 xattr.override_redirect = True; 350 xattr.override_redirect = True;
339 xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0; 351 xattr.background_pixel =
352 def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
340 xattr.border_pixel = 0; 353 xattr.border_pixel = 0;
341 xattr.colormap = SDL_XColorMap; 354 xattr.colormap = SDL_XColorMap;
342 355
343 FSwindow = XCreateWindow(SDL_Display, SDL_Root, 356 FSwindow = XCreateWindow(SDL_Display, SDL_Root,
344 x, y, 32, 32, 0, 357 x, y, 32, 32, 0,
345 this->hidden->depth, InputOutput, SDL_Visual, 358 this->hidden->depth, InputOutput, SDL_Visual,
346 CWOverrideRedirect | CWBackPixel | CWBorderPixel 359 CWOverrideRedirect | CWBackPixel | CWBorderPixel
347 | CWColormap, 360 | CWColormap, &xattr);
348 &xattr);
349 361
350 XSelectInput(SDL_Display, FSwindow, StructureNotifyMask); 362 XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);
351 363
352 /* Tell KDE to keep the fullscreen window on top */ 364 /* Tell KDE to keep the fullscreen window on top */
353 { 365 {
354 XEvent ev; 366 XEvent ev;
355 long mask; 367 long mask;
356 368
357 SDL_memset(&ev, 0, sizeof(ev)); 369 SDL_memset(&ev, 0, sizeof(ev));
358 ev.xclient.type = ClientMessage; 370 ev.xclient.type = ClientMessage;
359 ev.xclient.window = SDL_Root; 371 ev.xclient.window = SDL_Root;
360 ev.xclient.message_type = XInternAtom(SDL_Display, 372 ev.xclient.message_type = XInternAtom(SDL_Display,
361 "KWM_KEEP_ON_TOP", False); 373 "KWM_KEEP_ON_TOP", False);
362 ev.xclient.format = 32; 374 ev.xclient.format = 32;
363 ev.xclient.data.l[0] = FSwindow; 375 ev.xclient.data.l[0] = FSwindow;
364 ev.xclient.data.l[1] = CurrentTime; 376 ev.xclient.data.l[1] = CurrentTime;
365 mask = SubstructureRedirectMask; 377 mask = SubstructureRedirectMask;
366 XSendEvent(SDL_Display, SDL_Root, False, mask, &ev); 378 XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
367 } 379 }
368 380
369 hints = NULL; 381 hints = NULL;
370 if(WMwindow) { 382 if (WMwindow) {
371 /* All window attributes must survive the recreation */ 383 /* All window attributes must survive the recreation */
372 hints = XGetWMHints(SDL_Display, WMwindow); 384 hints = XGetWMHints(SDL_Display, WMwindow);
373 XDestroyWindow(SDL_Display, WMwindow); 385 XDestroyWindow(SDL_Display, WMwindow);
374 } 386 }
375 387
376 /* Create the window for windowed management */ 388 /* Create the window for windowed management */
377 /* (reusing the xattr structure above) */ 389 /* (reusing the xattr structure above) */
378 WMwindow = XCreateWindow(SDL_Display, SDL_Root, 390 WMwindow = XCreateWindow(SDL_Display, SDL_Root,
379 x, y, 32, 32, 0, 391 x, y, 32, 32, 0,
380 this->hidden->depth, InputOutput, SDL_Visual, 392 this->hidden->depth, InputOutput, SDL_Visual,
381 CWBackPixel | CWBorderPixel | CWColormap, 393 CWBackPixel | CWBorderPixel | CWColormap,
382 &xattr); 394 &xattr);
383 395
384 /* Set the input hints so we get keyboard input */ 396 /* Set the input hints so we get keyboard input */
385 if(!hints) { 397 if (!hints) {
386 hints = XAllocWMHints(); 398 hints = XAllocWMHints();
387 hints->input = True; 399 hints->input = True;
388 hints->flags = InputHint; 400 hints->flags = InputHint;
389 } 401 }
390 XSetWMHints(SDL_Display, WMwindow, hints); 402 XSetWMHints(SDL_Display, WMwindow, hints);
391 XFree(hints); 403 XFree(hints);
392 X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon); 404 X11_SetCaptionNoLock(this, SDL_CurrentWindow.wm_title,
405 SDL_CurrentWindow.wm_icon);
393 406
394 XSelectInput(SDL_Display, WMwindow, 407 XSelectInput(SDL_Display, WMwindow,
395 FocusChangeMask | KeyPressMask | KeyReleaseMask 408 FocusChangeMask | KeyPressMask | KeyReleaseMask
396 | PropertyChangeMask | StructureNotifyMask | KeymapStateMask); 409 | PropertyChangeMask | StructureNotifyMask |
410 KeymapStateMask);
397 411
398 /* Set the class hints so we can get an icon (AfterStep) */ 412 /* Set the class hints so we can get an icon (AfterStep) */
399 get_classname(classname, sizeof(classname)); 413 get_classname(classname, sizeof(classname));
400 { 414 {
401 XClassHint *classhints; 415 XClassHint *classhints;
402 classhints = XAllocClassHint(); 416 classhints = XAllocClassHint();
403 if(classhints != NULL) { 417 if (classhints != NULL) {
404 classhints->res_name = classname; 418 classhints->res_name = classname;
405 classhints->res_class = classname; 419 classhints->res_class = classname;
406 XSetClassHint(SDL_Display, WMwindow, classhints); 420 XSetClassHint(SDL_Display, WMwindow, classhints);
407 XFree(classhints); 421 XFree(classhints);
408 } 422 }
409 } 423 }
410 424
411 /* Setup the communication with the IM server */ 425 /* Setup the communication with the IM server */
412 SDL_IM = NULL; 426 SDL_IM = NULL;
413 SDL_IC = NULL; 427 SDL_IC = NULL;
414 428
415 #ifdef X_HAVE_UTF8_STRING 429 #ifdef X_HAVE_UTF8_STRING
416 if (SDL_X11_HAVE_UTF8) { 430 if (SDL_X11_HAVE_UTF8) {
417 SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname); 431 SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname);
418 if (SDL_IM == NULL) { 432 if (SDL_IM == NULL) {
419 SDL_SetError("no input method could be opened"); 433 SDL_SetError("no input method could be opened");
420 } else { 434 } else {
421 SDL_IC = pXCreateIC(SDL_IM, 435 SDL_IC = pXCreateIC(SDL_IM,
422 XNClientWindow, WMwindow, 436 XNClientWindow, WMwindow,
423 XNFocusWindow, WMwindow, 437 XNFocusWindow, WMwindow,
424 XNInputStyle, XIMPreeditNothing | XIMStatusNothing, 438 XNInputStyle,
425 XNResourceName, classname, 439 XIMPreeditNothing | XIMStatusNothing,
426 XNResourceClass, classname, 440 XNResourceName, classname,
427 NULL); 441 XNResourceClass, classname, NULL);
428 442
429 if (SDL_IC == NULL) { 443 if (SDL_IC == NULL) {
430 SDL_SetError("no input context could be created"); 444 SDL_SetError("no input context could be created");
431 XCloseIM(SDL_IM); 445 XCloseIM(SDL_IM);
432 SDL_IM = NULL; 446 SDL_IM = NULL;
433 } 447 }
434 } 448 }
435 } 449 }
436 #endif 450 #endif
437 451
438 /* Allow the window to be deleted by the window manager */ 452 /* Allow the window to be deleted by the window manager */
439 XSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1); 453 XSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);
440 } 454 }
441 455
442 static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) 456 static int
443 { 457 X11_VideoInit(_THIS)
444 char *display; 458 {
445 int i; 459 char *display;
446 460 int i;
447 /* Open the X11 display */ 461 SDL_DisplayMode desktop_mode;
448 display = NULL; /* Get it from DISPLAY environment variable */ 462
449 463 /* Open the X11 display */
450 if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) || 464 display = NULL; /* Get it from DISPLAY environment variable */
451 (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) { 465
452 local_X11 = 1; 466 if ((SDL_strncmp(XDisplayName(display), ":", 1) == 0) ||
453 } else { 467 (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0)) {
454 local_X11 = 0; 468 local_X11 = 1;
455 } 469 } else {
456 SDL_Display = XOpenDisplay(display); 470 local_X11 = 0;
471 }
472 SDL_Display = XOpenDisplay(display);
457 #if defined(__osf__) && defined(SDL_VIDEO_DRIVER_X11_DYNAMIC) 473 #if defined(__osf__) && defined(SDL_VIDEO_DRIVER_X11_DYNAMIC)
458 /* On Tru64 if linking without -lX11, it fails and you get following message. 474 /* On Tru64 if linking without -lX11, it fails and you get following message.
459 * Xlib: connection to ":0.0" refused by server 475 * Xlib: connection to ":0.0" refused by server
460 * Xlib: XDM authorization key matches an existing client! 476 * Xlib: XDM authorization key matches an existing client!
461 * 477 *
462 * It succeeds if retrying 1 second later 478 * It succeeds if retrying 1 second later
463 * or if running xhost +localhost on shell. 479 * or if running xhost +localhost on shell.
464 * 480 *
465 */ 481 */
466 if ( SDL_Display == NULL ) { 482 if (SDL_Display == NULL) {
467 SDL_Delay(1000); 483 SDL_Delay(1000);
468 SDL_Display = XOpenDisplay(display); 484 SDL_Display = XOpenDisplay(display);
469 } 485 }
470 #endif 486 #endif
471 if ( SDL_Display == NULL ) { 487 if (SDL_Display == NULL) {
472 SDL_SetError("Couldn't open X11 display"); 488 SDL_SetError("Couldn't open X11 display");
473 return(-1); 489 return (-1);
474 } 490 }
475 #ifdef X11_DEBUG 491 #ifdef X11_DEBUG
476 XSynchronize(SDL_Display, True); 492 XSynchronize(SDL_Display, True);
477 #endif 493 #endif
478 494
479 /* Create an alternate X display for graphics updates -- allows us 495 /* Create an alternate X display for graphics updates -- allows us
480 to do graphics updates in a separate thread from event handling. 496 to do graphics updates in a separate thread from event handling.
481 Thread-safe X11 doesn't seem to exist. 497 Thread-safe X11 doesn't seem to exist.
482 */ 498 */
483 GFX_Display = XOpenDisplay(display); 499 GFX_Display = XOpenDisplay(display);
484 if ( GFX_Display == NULL ) { 500 if (GFX_Display == NULL) {
485 SDL_SetError("Couldn't open X11 display"); 501 SDL_SetError("Couldn't open X11 display");
486 return(-1); 502 return (-1);
487 } 503 }
488 504
489 /* Set the normal X error handler */ 505 /* Set the normal X error handler */
490 X_handler = XSetErrorHandler(x_errhandler); 506 X_handler = XSetErrorHandler(x_errhandler);
491 507
492 /* Set the error handler if we lose the X display */ 508 /* Set the error handler if we lose the X display */
493 XIO_handler = XSetIOErrorHandler(xio_errhandler); 509 XIO_handler = XSetIOErrorHandler(xio_errhandler);
494 510
495 /* Set the X extension error handler */ 511 /* Set the X extension error handler */
496 Xext_handler = XSetExtensionErrorHandler(xext_errhandler); 512 Xext_handler = XSetExtensionErrorHandler(xext_errhandler);
497 513
498 /* use default screen (from $DISPLAY) */ 514 /* use default screen (from $DISPLAY) */
499 SDL_Screen = DefaultScreen(SDL_Display); 515 SDL_Screen = DefaultScreen(SDL_Display);
500 516
501 #ifndef NO_SHARED_MEMORY 517 #ifndef NO_SHARED_MEMORY
502 /* Check for MIT shared memory extension */ 518 /* Check for MIT shared memory extension */
503 use_mitshm = 0; 519 use_mitshm = 0;
504 if ( local_X11 ) { 520 if (local_X11) {
505 use_mitshm = XShmQueryExtension(SDL_Display); 521 use_mitshm = XShmQueryExtension(SDL_Display);
506 } 522 }
507 #endif /* NO_SHARED_MEMORY */ 523 #endif /* NO_SHARED_MEMORY */
508 524
509 /* Get the available video modes */ 525 /* Get the available visuals */
510 if(X11_GetVideoModes(this) < 0) 526 if (X11_GetVisuals(this) < 0)
511 return -1; 527 return -1;
512 528
513 /* Determine the current screen size */ 529 /* Determine the default screen mode:
514 this->info.current_w = DisplayWidth(SDL_Display, SDL_Screen); 530 Use the default visual (or at least one with the same depth) */
515 this->info.current_h = DisplayHeight(SDL_Display, SDL_Screen); 531 SDL_DisplayColormap = DefaultColormap(SDL_Display, SDL_Screen);
516 532 for (i = 0; i < this->hidden->nvisuals; i++)
517 /* Determine the default screen depth: 533 if (this->hidden->visuals[i].depth == DefaultDepth(SDL_Display,
518 Use the default visual (or at least one with the same depth) */ 534 SDL_Screen))
519 SDL_DisplayColormap = DefaultColormap(SDL_Display, SDL_Screen); 535 break;
520 for(i = 0; i < this->hidden->nvisuals; i++) 536 if (i == this->hidden->nvisuals) {
521 if(this->hidden->visuals[i].depth == DefaultDepth(SDL_Display, 537 /* default visual was useless, take the deepest one instead */
522 SDL_Screen)) 538 i = 0;
523 break; 539 }
524 if(i == this->hidden->nvisuals) { 540 SDL_Visual = this->hidden->visuals[i].visual;
525 /* default visual was useless, take the deepest one instead */ 541 if (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen)) {
526 i = 0; 542 SDL_XColorMap = SDL_DisplayColormap;
527 } 543 } else {
528 SDL_Visual = this->hidden->visuals[i].visual; 544 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
529 if ( SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen) ) { 545 SDL_Visual, AllocNone);
530 SDL_XColorMap = SDL_DisplayColormap; 546 }
531 } else { 547 desktop_mode.format =
532 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, 548 X11_VisualToFormat(this->hidden->visuals[i].visual,
533 SDL_Visual, AllocNone); 549 this->hidden->visuals[i].depth,
534 } 550 this->hidden->visuals[i].bpp);
535 this->hidden->depth = this->hidden->visuals[i].depth; 551 desktop_mode.w = DisplayWidth(SDL_Display, SDL_Screen);
536 vformat->BitsPerPixel = this->hidden->visuals[i].bpp; 552 desktop_mode.h = DisplayHeight(SDL_Display, SDL_Screen);
537 if ( vformat->BitsPerPixel > 8 ) { 553 desktop_mode.refresh_rate = 0;
538 vformat->Rmask = SDL_Visual->red_mask; 554 SDL_AddVideoDisplay(&desktop_mode);
539 vformat->Gmask = SDL_Visual->green_mask; 555
540 vformat->Bmask = SDL_Visual->blue_mask; 556 /* Get the available video modes */
541 } 557 if (X11_GetVideoModes(this) < 0)
542 if ( this->hidden->depth == 32 ) { 558 return -1;
543 vformat->Amask = (0xFFFFFFFF & ~(vformat->Rmask|vformat->Gmask|vformat->Bmask)); 559
544 } 560 X11_SaveVidModeGamma(this);
545 X11_SaveVidModeGamma(this); 561
546 562 /* Save DPMS and screensaver settings */
547 /* Save DPMS and screensaver settings */ 563 X11_SaveScreenSaver(SDL_Display, &screensaver_timeout, &dpms_enabled);
548 X11_SaveScreenSaver(SDL_Display, &screensaver_timeout, &dpms_enabled); 564 X11_DisableScreenSaver(SDL_Display);
549 X11_DisableScreenSaver(SDL_Display); 565
550 566 /* See if we have been passed a window to use */
551 /* See if we have been passed a window to use */ 567 SDL_windowid = SDL_getenv("SDL_WINDOWID");
552 SDL_windowid = SDL_getenv("SDL_WINDOWID"); 568
553 569 /* Create the fullscreen and managed windows */
554 /* Create the fullscreen and managed windows */ 570 create_aux_windows(this);
555 create_aux_windows(this); 571
556 572 /* Create the blank cursor */
557 /* Create the blank cursor */ 573 SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
558 SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, 574 BLANK_CWIDTH, BLANK_CHEIGHT,
559 BLANK_CWIDTH, BLANK_CHEIGHT, 575 BLANK_CHOTX, BLANK_CHOTY);
560 BLANK_CHOTX, BLANK_CHOTY); 576
561 577 /* Fill in some window manager capabilities */
562 /* Fill in some window manager capabilities */ 578 this->info.wm_available = 1;
563 this->info.wm_available = 1; 579
564 580 /* We're done! */
565 /* We're done! */ 581 XFlush(SDL_Display);
566 XFlush(SDL_Display); 582 return (0);
567 return(0); 583 }
568 } 584
569 585 static void
570 static void X11_DestroyWindow(_THIS, SDL_Surface *screen) 586 X11_DestroyWindow(_THIS, SDL_Surface * screen)
571 { 587 {
572 /* Clean up OpenGL */ 588 /* Clean up OpenGL */
573 if ( screen ) { 589 if (screen) {
574 screen->flags &= ~(SDL_OPENGL|SDL_OPENGLBLIT); 590 screen->flags &= ~SDL_INTERNALOPENGL;
575 } 591 }
576 X11_GL_Shutdown(this); 592 X11_GL_Shutdown(this);
577 593
578 if ( ! SDL_windowid ) { 594 if (!SDL_windowid) {
579 /* Hide the managed window */ 595 /* Hide the managed window */
580 if ( WMwindow ) { 596 if (WMwindow) {
581 XUnmapWindow(SDL_Display, WMwindow); 597 XUnmapWindow(SDL_Display, WMwindow);
582 } 598 }
583 if ( screen && (screen->flags & SDL_FULLSCREEN) ) { 599 if (screen && (screen->flags & SDL_FULLSCREEN)) {
584 screen->flags &= ~SDL_FULLSCREEN; 600 screen->flags &= ~SDL_FULLSCREEN;
585 X11_LeaveFullScreen(this); 601 X11_LeaveFullScreen(this);
586 } 602 }
587 603
588 /* Destroy the output window */ 604 /* Destroy the output window */
589 if ( SDL_Window ) { 605 if (SDL_Window) {
590 XDestroyWindow(SDL_Display, SDL_Window); 606 XDestroyWindow(SDL_Display, SDL_Window);
591 } 607 }
592 608
593 /* Free the colormap entries */ 609 /* Free the colormap entries */
594 if ( SDL_XPixels ) { 610 if (SDL_XPixels) {
595 int numcolors; 611 int numcolors;
596 unsigned long pixel; 612 unsigned long pixel;
597 numcolors = SDL_Visual->map_entries; 613 numcolors = SDL_Visual->map_entries;
598 for ( pixel=0; pixel<numcolors; ++pixel ) { 614 for (pixel = 0; pixel < numcolors; ++pixel) {
599 while ( SDL_XPixels[pixel] > 0 ) { 615 while (SDL_XPixels[pixel] > 0) {
600 XFreeColors(GFX_Display, 616 XFreeColors(GFX_Display,
601 SDL_DisplayColormap,&pixel,1,0); 617 SDL_DisplayColormap, &pixel, 1, 0);
602 --SDL_XPixels[pixel]; 618 --SDL_XPixels[pixel];
603 } 619 }
604 } 620 }
605 SDL_free(SDL_XPixels); 621 SDL_free(SDL_XPixels);
606 SDL_XPixels = NULL; 622 SDL_XPixels = NULL;
607 } 623 }
608 624
609 /* Free the graphics context */ 625 /* Free the graphics context */
610 if ( SDL_GC ) { 626 if (SDL_GC) {
611 XFreeGC(SDL_Display, SDL_GC); 627 XFreeGC(SDL_Display, SDL_GC);
612 SDL_GC = 0; 628 SDL_GC = 0;
613 } 629 }
614 } 630 }
615 } 631 }
616 632
617 static SDL_bool X11_WindowPosition(_THIS, int *x, int *y, int w, int h) 633 static SDL_bool
618 { 634 X11_WindowPosition(_THIS, int *x, int *y, int w, int h)
619 const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); 635 {
620 const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); 636 const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
621 if ( window ) { 637 const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
622 if ( SDL_sscanf(window, "%d,%d", x, y) == 2 ) { 638 if (window) {
623 return SDL_TRUE; 639 if (SDL_sscanf(window, "%d,%d", x, y) == 2) {
624 } 640 return SDL_TRUE;
625 if ( SDL_strcmp(window, "center") == 0 ) { 641 }
626 center = window; 642 if (SDL_strcmp(window, "center") == 0) {
627 } 643 center = window;
628 } 644 }
629 if ( center ) { 645 }
630 *x = (DisplayWidth(SDL_Display, SDL_Screen) - w)/2; 646 if (center) {
631 *y = (DisplayHeight(SDL_Display, SDL_Screen) - h)/2; 647 *x = (DisplayWidth(SDL_Display, SDL_Screen) - w) / 2;
632 return SDL_TRUE; 648 *y = (DisplayHeight(SDL_Display, SDL_Screen) - h) / 2;
633 } 649 return SDL_TRUE;
634 return SDL_FALSE; 650 }
635 } 651 return SDL_FALSE;
636 652 }
637 static void X11_SetSizeHints(_THIS, int w, int h, Uint32 flags) 653
638 { 654 static void
639 XSizeHints *hints; 655 X11_SetSizeHints(_THIS, int w, int h, Uint32 flags)
640 656 {
641 hints = XAllocSizeHints(); 657 XSizeHints *hints;
642 if ( hints ) { 658
643 if ( flags & SDL_RESIZABLE ) { 659 hints = XAllocSizeHints();
644 hints->min_width = 32; 660 if (hints) {
645 hints->min_height = 32; 661 if (flags & SDL_RESIZABLE) {
646 hints->max_height = 4096; 662 hints->min_width = 32;
647 hints->max_width = 4096; 663 hints->min_height = 32;
648 } else { 664 hints->max_height = 4096;
649 hints->min_width = hints->max_width = w; 665 hints->max_width = 4096;
650 hints->min_height = hints->max_height = h; 666 } else {
651 } 667 hints->min_width = hints->max_width = w;
652 hints->flags = PMaxSize | PMinSize; 668 hints->min_height = hints->max_height = h;
653 if ( flags & SDL_FULLSCREEN ) { 669 }
654 hints->x = 0; 670 hints->flags = PMaxSize | PMinSize;
655 hints->y = 0; 671 if (flags & SDL_FULLSCREEN) {
656 hints->flags |= USPosition; 672 hints->x = 0;
657 } else 673 hints->y = 0;
658 /* Center it, if desired */ 674 hints->flags |= USPosition;
659 if ( X11_WindowPosition(this, &hints->x, &hints->y, w, h) ) { 675 } else
660 hints->flags |= USPosition; 676 /* Center it, if desired */
661 XMoveWindow(SDL_Display, WMwindow, hints->x, hints->y); 677 if (X11_WindowPosition(this, &hints->x, &hints->y, w, h)) {
662 678 hints->flags |= USPosition;
663 /* Flush the resize event so we don't catch it later */ 679 XMoveWindow(SDL_Display, WMwindow, hints->x, hints->y);
664 XSync(SDL_Display, True); 680
665 } 681 /* Flush the resize event so we don't catch it later */
666 XSetWMNormalHints(SDL_Display, WMwindow, hints); 682 XSync(SDL_Display, True);
667 XFree(hints); 683 }
668 } 684 XSetWMNormalHints(SDL_Display, WMwindow, hints);
669 685 XFree(hints);
670 /* Respect the window caption style */ 686 }
671 if ( flags & SDL_NOFRAME ) { 687
672 SDL_bool set; 688 /* Respect the window caption style */
673 Atom WM_HINTS; 689 if (flags & SDL_NOFRAME) {
674 690 SDL_bool set;
675 /* We haven't modified the window manager hints yet */ 691 Atom WM_HINTS;
676 set = SDL_FALSE; 692
677 693 /* We haven't modified the window manager hints yet */
678 /* First try to set MWM hints */ 694 set = SDL_FALSE;
679 WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); 695
680 if ( WM_HINTS != None ) { 696 /* First try to set MWM hints */
681 /* Hints used by Motif compliant window managers */ 697 WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True);
682 struct { 698 if (WM_HINTS != None) {
683 unsigned long flags; 699 /* Hints used by Motif compliant window managers */
684 unsigned long functions; 700 struct
685 unsigned long decorations; 701 {
686 long input_mode; 702 unsigned long flags;
687 unsigned long status; 703 unsigned long functions;
688 } MWMHints = { (1L << 1), 0, 0, 0, 0 }; 704 unsigned long decorations;
689 705 long input_mode;
690 XChangeProperty(SDL_Display, WMwindow, 706 unsigned long status;
691 WM_HINTS, WM_HINTS, 32, 707 } MWMHints = {
692 PropModeReplace, 708 (1L << 1), 0, 0, 0, 0};
693 (unsigned char *)&MWMHints, 709
694 sizeof(MWMHints)/sizeof(long)); 710 XChangeProperty(SDL_Display, WMwindow,
695 set = SDL_TRUE; 711 WM_HINTS, WM_HINTS, 32,
696 } 712 PropModeReplace,
697 /* Now try to set KWM hints */ 713 (unsigned char *) &MWMHints,
698 WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); 714 sizeof(MWMHints) / sizeof(long));
699 if ( WM_HINTS != None ) { 715 set = SDL_TRUE;
700 long KWMHints = 0; 716 }
701 717 /* Now try to set KWM hints */
702 XChangeProperty(SDL_Display, WMwindow, 718 WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True);
703 WM_HINTS, WM_HINTS, 32, 719 if (WM_HINTS != None) {
704 PropModeReplace, 720 long KWMHints = 0;
705 (unsigned char *)&KWMHints, 721
706 sizeof(KWMHints)/sizeof(long)); 722 XChangeProperty(SDL_Display, WMwindow,
707 set = SDL_TRUE; 723 WM_HINTS, WM_HINTS, 32,
708 } 724 PropModeReplace,
709 /* Now try to set GNOME hints */ 725 (unsigned char *) &KWMHints,
710 WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); 726 sizeof(KWMHints) / sizeof(long));
711 if ( WM_HINTS != None ) { 727 set = SDL_TRUE;
712 long GNOMEHints = 0; 728 }
713 729 /* Now try to set GNOME hints */
714 XChangeProperty(SDL_Display, WMwindow, 730 WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True);
715 WM_HINTS, WM_HINTS, 32, 731 if (WM_HINTS != None) {
716 PropModeReplace, 732 long GNOMEHints = 0;
717 (unsigned char *)&GNOMEHints, 733
718 sizeof(GNOMEHints)/sizeof(long)); 734 XChangeProperty(SDL_Display, WMwindow,
719 set = SDL_TRUE; 735 WM_HINTS, WM_HINTS, 32,
720 } 736 PropModeReplace,
721 /* Finally set the transient hints if necessary */ 737 (unsigned char *) &GNOMEHints,
722 if ( ! set ) { 738 sizeof(GNOMEHints) / sizeof(long));
723 XSetTransientForHint(SDL_Display, WMwindow, SDL_Root); 739 set = SDL_TRUE;
724 } 740 }
725 } else { 741 /* Finally set the transient hints if necessary */
726 SDL_bool set; 742 if (!set) {
727 Atom WM_HINTS; 743 XSetTransientForHint(SDL_Display, WMwindow, SDL_Root);
728 744 }
729 /* We haven't modified the window manager hints yet */ 745 } else {
730 set = SDL_FALSE; 746 SDL_bool set;
731 747 Atom WM_HINTS;
732 /* First try to unset MWM hints */ 748
733 WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); 749 /* We haven't modified the window manager hints yet */
734 if ( WM_HINTS != None ) { 750 set = SDL_FALSE;
735 XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); 751
736 set = SDL_TRUE; 752 /* First try to unset MWM hints */
737 } 753 WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True);
738 /* Now try to unset KWM hints */ 754 if (WM_HINTS != None) {
739 WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); 755 XDeleteProperty(SDL_Display, WMwindow, WM_HINTS);
740 if ( WM_HINTS != None ) { 756 set = SDL_TRUE;
741 XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); 757 }
742 set = SDL_TRUE; 758 /* Now try to unset KWM hints */
743 } 759 WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True);
744 /* Now try to unset GNOME hints */ 760 if (WM_HINTS != None) {
745 WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); 761 XDeleteProperty(SDL_Display, WMwindow, WM_HINTS);
746 if ( WM_HINTS != None ) { 762 set = SDL_TRUE;
747 XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); 763 }
748 set = SDL_TRUE; 764 /* Now try to unset GNOME hints */
749 } 765 WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True);
750 /* Finally unset the transient hints if necessary */ 766 if (WM_HINTS != None) {
751 if ( ! set ) { 767 XDeleteProperty(SDL_Display, WMwindow, WM_HINTS);
752 /* NOTE: Does this work? */ 768 set = SDL_TRUE;
753 XSetTransientForHint(SDL_Display, WMwindow, None); 769 }
754 } 770 /* Finally unset the transient hints if necessary */
755 } 771 if (!set) {
756 } 772 /* NOTE: Does this work? */
757 773 XSetTransientForHint(SDL_Display, WMwindow, None);
758 static int X11_CreateWindow(_THIS, SDL_Surface *screen, 774 }
759 int w, int h, int bpp, Uint32 flags) 775 }
760 { 776 }
761 int i, depth; 777
762 Visual *vis; 778 static int
763 int vis_change; 779 X11_CreateWindow(_THIS, SDL_Surface * screen,
764 Uint32 Amask; 780 const SDL_DisplayMode * mode, Uint32 flags)
765 781 {
766 /* If a window is already present, destroy it and start fresh */ 782 int i, depth;
767 if ( SDL_Window ) { 783 Visual *vis;
768 X11_DestroyWindow(this, screen); 784 int vis_change;
769 switch_waiting = 0; /* Prevent jump back to now-meaningless state. */ 785 int bpp;
770 } 786 Uint32 Rmask, Gmask, Bmask, Amask;
771 787
772 /* See if we have been given a window id */ 788 SDL_PixelFormatEnumToMasks(mode->format, &bpp, &Rmask, &Gmask, &Bmask,
773 if ( SDL_windowid ) { 789 &Amask);
774 SDL_Window = SDL_strtol(SDL_windowid, NULL, 0); 790
775 } else { 791 /* If a window is already present, destroy it and start fresh */
776 SDL_Window = 0; 792 if (SDL_Window) {
777 } 793 X11_DestroyWindow(this, screen);
778 794 switch_waiting = 0; /* Prevent jump back to now-meaningless state. */
779 /* find out which visual we are going to use */ 795 }
780 if ( flags & SDL_OPENGL ) { 796
781 XVisualInfo *vi; 797 /* See if we have been given a window id */
782 798 if (SDL_windowid) {
783 vi = X11_GL_GetVisual(this); 799 SDL_Window = SDL_strtol(SDL_windowid, NULL, 0);
784 if( !vi ) { 800 } else {
785 return -1; 801 SDL_Window = 0;
786 } 802 }
787 vis = vi->visual; 803
788 depth = vi->depth; 804 /* find out which visual we are going to use */
789 } else if ( SDL_windowid ) { 805 if (flags & SDL_INTERNALOPENGL) {
790 XWindowAttributes a; 806 XVisualInfo *vi;
791 807
792 XGetWindowAttributes(SDL_Display, SDL_Window, &a); 808 vi = X11_GL_GetVisual(this);
793 vis = a.visual; 809 if (!vi) {
794 depth = a.depth; 810 return -1;
795 } else { 811 }
796 for ( i = 0; i < this->hidden->nvisuals; i++ ) { 812 vis = vi->visual;
797 if ( this->hidden->visuals[i].bpp == bpp ) 813 depth = vi->depth;
798 break; 814 } else if (SDL_windowid) {
799 } 815 XWindowAttributes a;
800 if ( i == this->hidden->nvisuals ) { 816
801 SDL_SetError("No matching visual for requested depth"); 817 XGetWindowAttributes(SDL_Display, SDL_Window, &a);
802 return -1; /* should never happen */ 818 vis = a.visual;
803 } 819 depth = a.depth;
804 vis = this->hidden->visuals[i].visual; 820 } else {
805 depth = this->hidden->visuals[i].depth; 821 for (i = 0; i < this->hidden->nvisuals; i++) {
806 } 822 if (this->hidden->visuals[i].bpp == bpp &&
823 this->hidden->visuals[i].visual->red_mask == Rmask &&
824 this->hidden->visuals[i].visual->green_mask == Gmask &&
825 this->hidden->visuals[i].visual->blue_mask == Bmask)
826 break;
827 }
828 if (i == this->hidden->nvisuals) {
829 SDL_SetError("No matching visual for requested depth");
830 return -1; /* should never happen */
831 }
832 vis = this->hidden->visuals[i].visual;
833 depth = this->hidden->visuals[i].depth;
834 }
807 #ifdef X11_DEBUG 835 #ifdef X11_DEBUG
808 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); 836 printf("Choosing %s visual at %d bpp - %d colormap entries\n",
809 #endif 837 vis->class == PseudoColor ? "PseudoColor" : (vis->class ==
810 vis_change = (vis != SDL_Visual); 838 TrueColor ?
811 SDL_Visual = vis; 839 "TrueColor" : (vis->
812 this->hidden->depth = depth; 840 class
813 841 ==
814 /* Allocate the new pixel format for this video mode */ 842 DirectColor
815 if ( this->hidden->depth == 32 ) { 843 ?
816 Amask = (0xFFFFFFFF & ~(vis->red_mask|vis->green_mask|vis->blue_mask)); 844 "DirectColor"
817 } else { 845 :
818 Amask = 0; 846 "Unknown")),
819 } 847 depth, vis->map_entries);
820 if ( ! SDL_ReallocFormat(screen, bpp, 848 #endif
821 vis->red_mask, vis->green_mask, vis->blue_mask, Amask) ) { 849 vis_change = (vis != SDL_Visual);
822 return -1; 850 SDL_Visual = vis;
823 } 851 this->hidden->depth = depth;
824 852
825 /* Create the appropriate colormap */ 853 /* Allocate the new pixel format for this video mode */
826 if ( SDL_XColorMap != SDL_DisplayColormap ) { 854 if (!SDL_ReallocFormat(screen, bpp, Rmask, Gmask, Bmask, Amask)) {
827 XFreeColormap(SDL_Display, SDL_XColorMap); 855 return -1;
828 } 856 }
829 if ( SDL_Visual->class == PseudoColor ) { 857
830 int ncolors; 858 /* Create the appropriate colormap */
831 859 if (SDL_XColorMap != SDL_DisplayColormap) {
832 /* Allocate the pixel flags */ 860 XFreeColormap(SDL_Display, SDL_XColorMap);
833 ncolors = SDL_Visual->map_entries; 861 }
834 SDL_XPixels = SDL_malloc(ncolors * sizeof(int)); 862 if (SDL_Visual->class == PseudoColor) {
835 if(SDL_XPixels == NULL) { 863 int ncolors;
836 SDL_OutOfMemory(); 864
837 return -1; 865 /* Allocate the pixel flags */
838 } 866 ncolors = SDL_Visual->map_entries;
839 SDL_memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels)); 867 SDL_XPixels = SDL_malloc(ncolors * sizeof(int));
840 868 if (SDL_XPixels == NULL) {
841 /* always allocate a private colormap on non-default visuals */ 869 SDL_OutOfMemory();
842 if ( SDL_Visual != DefaultVisual(SDL_Display, SDL_Screen) ) { 870 return -1;
843 flags |= SDL_HWPALETTE; 871 }
844 } 872 SDL_memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels));
845 if ( flags & SDL_HWPALETTE ) { 873
846 screen->flags |= SDL_HWPALETTE; 874 /* always allocate a private colormap on non-default visuals */
847 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, 875 if (SDL_Visual != DefaultVisual(SDL_Display, SDL_Screen)) {
848 SDL_Visual, AllocAll); 876 flags |= SDL_HWPALETTE;
849 } else { 877 }
850 SDL_XColorMap = SDL_DisplayColormap; 878 if (flags & SDL_HWPALETTE) {
851 } 879 screen->flags |= SDL_HWPALETTE;
852 } else if ( SDL_Visual->class == DirectColor ) { 880 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
853 881 SDL_Visual, AllocAll);
854 /* Create a colormap which we can manipulate for gamma */ 882 } else {
855 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, 883 SDL_XColorMap = SDL_DisplayColormap;
856 SDL_Visual, AllocAll); 884 }
857 XSync(SDL_Display, False); 885 } else if (SDL_Visual->class == DirectColor) {
858 886
859 /* Initialize the colormap to the identity mapping */ 887 /* Create a colormap which we can manipulate for gamma */
860 SDL_GetGammaRamp(0, 0, 0); 888 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
861 this->screen = screen; 889 SDL_Visual, AllocAll);
862 X11_SetGammaRamp(this, this->gamma); 890 XSync(SDL_Display, False);
863 this->screen = NULL; 891
864 } else { 892 /* Initialize the colormap to the identity mapping */
865 /* Create a read-only colormap for our window */ 893 SDL_GetGammaRamp(0, 0, 0);
866 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, 894 SDL_VideoSurface = screen;
867 SDL_Visual, AllocNone); 895 X11_SetGammaRamp(this, SDL_CurrentWindow.gamma);
868 } 896 SDL_VideoSurface = NULL;
869 897 } else {
870 /* Recreate the auxiliary windows, if needed (required for GL) */ 898 /* Create a read-only colormap for our window */
871 if ( vis_change ) 899 SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
872 create_aux_windows(this); 900 SDL_Visual, AllocNone);
873 901 }
874 if(screen->flags & SDL_HWPALETTE) { 902
875 /* Since the full-screen window might have got a nonzero background 903 /* Recreate the auxiliary windows, if needed (required for GL) */
876 colour (0 is white on some displays), we should reset the 904 if (vis_change)
877 background to 0 here since that is what the user expects 905 create_aux_windows(this);
878 with a private colormap */ 906
879 XSetWindowBackground(SDL_Display, FSwindow, 0); 907 if (screen->flags & SDL_HWPALETTE) {
880 XClearWindow(SDL_Display, FSwindow); 908 /* Since the full-screen window might have got a nonzero background
881 } 909 colour (0 is white on some displays), we should reset the
882 910 background to 0 here since that is what the user expects
883 /* resize the (possibly new) window manager window */ 911 with a private colormap */
884 if( !SDL_windowid ) { 912 XSetWindowBackground(SDL_Display, FSwindow, 0);
885 X11_SetSizeHints(this, w, h, flags); 913 XClearWindow(SDL_Display, FSwindow);
886 window_w = w; 914 }
887 window_h = h; 915
888 XResizeWindow(SDL_Display, WMwindow, w, h); 916 /* resize the (possibly new) window manager window */
889 } 917 if (!SDL_windowid) {
890 918 X11_SetSizeHints(this, mode->w, mode->h, flags);
891 /* Create (or use) the X11 display window */ 919 window_w = mode->w;
892 if ( !SDL_windowid ) { 920 window_h = mode->h;
893 if ( flags & SDL_OPENGL ) { 921 XResizeWindow(SDL_Display, WMwindow, mode->w, mode->h);
894 if ( X11_GL_CreateWindow(this, w, h) < 0 ) { 922 }
895 return(-1); 923
896 } 924 /* Create (or use) the X11 display window */
897 } else { 925 if (!SDL_windowid) {
898 XSetWindowAttributes swa; 926 if (flags & SDL_INTERNALOPENGL) {
899 927 if (X11_GL_CreateWindow(this, mode->w, mode->h) < 0) {
900 swa.background_pixel = 0; 928 return (-1);
901 swa.border_pixel = 0; 929 }
902 swa.colormap = SDL_XColorMap; 930 } else {
903 SDL_Window = XCreateWindow(SDL_Display, WMwindow, 931 XSetWindowAttributes swa;
904 0, 0, w, h, 0, depth, 932
905 InputOutput, SDL_Visual, 933 swa.background_pixel = 0;
906 CWBackPixel | CWBorderPixel 934 swa.border_pixel = 0;
907 | CWColormap, &swa); 935 swa.colormap = SDL_XColorMap;
908 } 936 SDL_Window = XCreateWindow(SDL_Display, WMwindow,
909 /* Only manage our input if we own the window */ 937 0, 0, mode->w, mode->h, 0, depth,
910 XSelectInput(SDL_Display, SDL_Window, 938 InputOutput, SDL_Visual,
911 ( EnterWindowMask | LeaveWindowMask 939 CWBackPixel | CWBorderPixel
912 | ButtonPressMask | ButtonReleaseMask 940 | CWColormap, &swa);
913 | PointerMotionMask | ExposureMask )); 941 }
914 } 942 /* Only manage our input if we own the window */
915 /* Create the graphics context here, once we have a window */ 943 XSelectInput(SDL_Display, SDL_Window,
916 if ( flags & SDL_OPENGL ) { 944 (EnterWindowMask | LeaveWindowMask
917 if ( X11_GL_CreateContext(this) < 0 ) { 945 | ButtonPressMask | ButtonReleaseMask
918 return(-1); 946 | PointerMotionMask | ExposureMask));
919 } else { 947 }
920 screen->flags |= SDL_OPENGL; 948 /* Create the graphics context here, once we have a window */
921 } 949 if (flags & SDL_INTERNALOPENGL) {
922 } else { 950 if (X11_GL_CreateContext(this) < 0) {
923 XGCValues gcv; 951 return (-1);
924 952 } else {
925 gcv.graphics_exposures = False; 953 screen->flags |= SDL_INTERNALOPENGL;
926 SDL_GC = XCreateGC(SDL_Display, SDL_Window, 954 }
927 GCGraphicsExposures, &gcv); 955 } else {
928 if ( ! SDL_GC ) { 956 XGCValues gcv;
929 SDL_SetError("Couldn't create graphics context"); 957
930 return(-1); 958 gcv.graphics_exposures = False;
931 } 959 SDL_GC = XCreateGC(SDL_Display, SDL_Window,
932 } 960 GCGraphicsExposures, &gcv);
933 961 if (!SDL_GC) {
934 /* Set our colormaps when not setting a GL mode */ 962 SDL_SetError("Couldn't create graphics context");
935 if ( ! (flags & SDL_OPENGL) ) { 963 return (-1);
936 XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap); 964 }
937 if( !SDL_windowid ) { 965 }
938 XSetWindowColormap(SDL_Display, FSwindow, SDL_XColorMap); 966
939 XSetWindowColormap(SDL_Display, WMwindow, SDL_XColorMap); 967 /* Set our colormaps when not setting a GL mode */
940 } 968 if (!(flags & SDL_INTERNALOPENGL)) {
941 } 969 XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap);
942 970 if (!SDL_windowid) {
943 #if 0 /* This is an experiment - are the graphics faster now? - nope. */ 971 XSetWindowColormap(SDL_Display, FSwindow, SDL_XColorMap);
944 if ( SDL_getenv("SDL_VIDEO_X11_BACKINGSTORE") ) 972 XSetWindowColormap(SDL_Display, WMwindow, SDL_XColorMap);
945 #endif 973 }
946 /* Cache the window in the server, when possible */ 974 }
947 { 975 #if 0 /* This is an experiment - are the graphics faster now? - nope. */
948 Screen *xscreen; 976 if (SDL_getenv("SDL_VIDEO_X11_BACKINGSTORE"))
949 XSetWindowAttributes a; 977 #endif
950 978 /* Cache the window in the server, when possible */
951 xscreen = ScreenOfDisplay(SDL_Display, SDL_Screen); 979 {
952 a.backing_store = DoesBackingStore(xscreen); 980 Screen *xscreen;
953 if ( a.backing_store != NotUseful ) { 981 XSetWindowAttributes a;
954 XChangeWindowAttributes(SDL_Display, SDL_Window, 982
955 CWBackingStore, &a); 983 xscreen = ScreenOfDisplay(SDL_Display, SDL_Screen);
956 } 984 a.backing_store = DoesBackingStore(xscreen);
957 } 985 if (a.backing_store != NotUseful) {
958 986 XChangeWindowAttributes(SDL_Display, SDL_Window,
959 /* Update the internal keyboard state */ 987 CWBackingStore, &a);
960 X11_SetKeyboardState(SDL_Display, NULL); 988 }
961 989 }
962 /* When the window is first mapped, ignore non-modifier keys */ 990
963 { 991 /* Update the internal keyboard state */
964 Uint8 *keys = SDL_GetKeyState(NULL); 992 X11_SetKeyboardState(SDL_Display, NULL);
965 for ( i = 0; i < SDLK_LAST; ++i ) { 993
966 switch (i) { 994 /* When the window is first mapped, ignore non-modifier keys */
967 case SDLK_NUMLOCK: 995 {
968 case SDLK_CAPSLOCK: 996 Uint8 *keys = SDL_GetKeyState(NULL);
969 case SDLK_LCTRL: 997 for (i = 0; i < SDLK_LAST; ++i) {
970 case SDLK_RCTRL: 998 switch (i) {
971 case SDLK_LSHIFT: 999 case SDLK_NUMLOCK:
972 case SDLK_RSHIFT: 1000 case SDLK_CAPSLOCK:
973 case SDLK_LALT: 1001 case SDLK_LCTRL:
974 case SDLK_RALT: 1002 case SDLK_RCTRL:
975 case SDLK_LMETA: 1003 case SDLK_LSHIFT:
976 case SDLK_RMETA: 1004 case SDLK_RSHIFT:
977 case SDLK_MODE: 1005 case SDLK_LALT:
978 break; 1006 case SDLK_RALT:
979 default: 1007 case SDLK_LMETA:
980 keys[i] = SDL_RELEASED; 1008 case SDLK_RMETA:
981 break; 1009 case SDLK_MODE:
982 } 1010 break;
983 } 1011 default:
984 } 1012 keys[i] = SDL_RELEASED;
985 1013 break;
986 /* Map them both and go fullscreen, if requested */ 1014 }
987 if ( ! SDL_windowid ) { 1015 }
988 XMapWindow(SDL_Display, SDL_Window); 1016 }
989 XMapWindow(SDL_Display, WMwindow); 1017
990 X11_WaitMapped(this, WMwindow); 1018 /* Map them both and go fullscreen, if requested */
991 if ( flags & SDL_FULLSCREEN ) { 1019 if (!SDL_windowid) {
992 screen->flags |= SDL_FULLSCREEN; 1020 XMapWindow(SDL_Display, SDL_Window);
993 X11_EnterFullScreen(this); 1021 XMapWindow(SDL_Display, WMwindow);
994 } else { 1022 X11_WaitMapped(this, WMwindow);
995 screen->flags &= ~SDL_FULLSCREEN; 1023 if (flags & SDL_FULLSCREEN) {
996 } 1024 screen->flags |= SDL_FULLSCREEN;
997 } 1025 X11_EnterFullScreen(this);
998 1026 } else {
999 return(0); 1027 screen->flags &= ~SDL_FULLSCREEN;
1000 } 1028 }
1001 1029 }
1002 static int X11_ResizeWindow(_THIS, 1030
1003 SDL_Surface *screen, int w, int h, Uint32 flags) 1031 return (0);
1004 { 1032 }
1005 if ( ! SDL_windowid ) { 1033
1006 /* Resize the window manager window */ 1034 static int
1007 X11_SetSizeHints(this, w, h, flags); 1035 X11_ResizeWindow(_THIS, SDL_Surface * screen, int w, int h, Uint32 flags)
1008 window_w = w; 1036 {
1009 window_h = h; 1037 if (!SDL_windowid) {
1010 XResizeWindow(SDL_Display, WMwindow, w, h); 1038 /* Resize the window manager window */
1011 1039 X11_SetSizeHints(this, w, h, flags);
1012 /* Resize the fullscreen and display windows */ 1040 window_w = w;
1013 if ( flags & SDL_FULLSCREEN ) { 1041 window_h = h;
1014 if ( screen->flags & SDL_FULLSCREEN ) { 1042 XResizeWindow(SDL_Display, WMwindow, w, h);
1015 X11_ResizeFullScreen(this); 1043
1016 } else { 1044 /* Resize the fullscreen and display windows */
1017 screen->flags |= SDL_FULLSCREEN; 1045 if (flags & SDL_FULLSCREEN) {
1018 X11_EnterFullScreen(this); 1046 if (screen->flags & SDL_FULLSCREEN) {
1019 } 1047 X11_ResizeFullScreen(this);
1020 } else { 1048 } else {
1021 if ( screen->flags & SDL_FULLSCREEN ) { 1049 screen->flags |= SDL_FULLSCREEN;
1022 screen->flags &= ~SDL_FULLSCREEN; 1050 X11_EnterFullScreen(this);
1023 X11_LeaveFullScreen(this); 1051 }
1024 } 1052 } else {
1025 } 1053 if (screen->flags & SDL_FULLSCREEN) {
1026 XResizeWindow(SDL_Display, SDL_Window, w, h); 1054 screen->flags &= ~SDL_FULLSCREEN;
1027 } 1055 X11_LeaveFullScreen(this);
1028 return(0); 1056 }
1029 } 1057 }
1030 1058 XResizeWindow(SDL_Display, SDL_Window, w, h);
1031 SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, 1059 }
1032 int width, int height, int bpp, Uint32 flags) 1060 return (0);
1033 { 1061 }
1034 Uint32 saved_flags; 1062
1035 1063 SDL_Surface *
1036 /* Lock the event thread, in multi-threading environments */ 1064 X11_SetVideoMode(_THIS, SDL_Surface * current,
1037 SDL_Lock_EventThread(); 1065 const SDL_DisplayMode * mode, Uint32 flags)
1038 1066 {
1039 /* Check the combination of flags we were passed */ 1067 Uint32 saved_flags;
1040 if ( flags & SDL_FULLSCREEN ) { 1068
1041 /* Clear fullscreen flag if not supported */ 1069 /* Lock the event thread, in multi-threading environments */
1042 if ( SDL_windowid ) { 1070 SDL_Lock_EventThread();
1043 flags &= ~SDL_FULLSCREEN; 1071
1044 } 1072 /* Check the combination of flags we were passed */
1045 } 1073 if (flags & SDL_FULLSCREEN) {
1046 1074 /* Clear fullscreen flag if not supported */
1047 /* Flush any delayed updates */ 1075 if (SDL_windowid) {
1048 XSync(GFX_Display, False); 1076 flags &= ~SDL_FULLSCREEN;
1049 1077 }
1050 /* Set up the X11 window */ 1078 }
1051 saved_flags = current->flags; 1079
1052 if ( (SDL_Window) && ((saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL)) 1080 /* Flush any delayed updates */
1053 && (bpp == current->format->BitsPerPixel) 1081 XSync(GFX_Display, False);
1054 && ((saved_flags&SDL_NOFRAME) == (flags&SDL_NOFRAME)) ) { 1082
1055 if (X11_ResizeWindow(this, current, width, height, flags) < 0) { 1083 /* Set up the X11 window */
1056 current = NULL; 1084 saved_flags = current->flags;
1057 goto done; 1085 if ((SDL_Window)
1058 } 1086 && ((saved_flags & SDL_INTERNALOPENGL) ==
1059 } else { 1087 (flags & SDL_INTERNALOPENGL))
1060 if (X11_CreateWindow(this,current,width,height,bpp,flags) < 0) { 1088 && (mode->format == SDL_CurrentDisplay.current_mode.format)
1061 current = NULL; 1089 && ((saved_flags & SDL_NOFRAME) == (flags & SDL_NOFRAME))) {
1062 goto done; 1090 if (X11_ResizeWindow(this, current, mode->w, mode->h, flags) < 0) {
1063 } 1091 current = NULL;
1064 } 1092 goto done;
1065 1093 }
1066 /* Set up the new mode framebuffer */ 1094 } else {
1067 if ( ((current->w != width) || (current->h != height)) || 1095 if (X11_CreateWindow(this, current, mode, flags) < 0) {
1068 ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) { 1096 current = NULL;
1069 current->w = width; 1097 goto done;
1070 current->h = height; 1098 }
1071 current->pitch = SDL_CalculatePitch(current); 1099 }
1072 X11_ResizeImage(this, current, flags); 1100
1073 } 1101 /* Set up the new mode framebuffer */
1074 current->flags |= (flags&(SDL_RESIZABLE|SDL_NOFRAME)); 1102 if (((current->w != mode->w) || (current->h != mode->h)) ||
1103 ((saved_flags & SDL_INTERNALOPENGL) != (flags & SDL_INTERNALOPENGL)))
1104 {
1105 current->w = mode->w;
1106 current->h = mode->h;
1107 current->pitch = SDL_CalculatePitch(current);
1108 X11_ResizeImage(this, current, flags);
1109 }
1110 current->flags |= (flags & (SDL_RESIZABLE | SDL_NOFRAME));
1075 1111
1076 done: 1112 done:
1077 /* Release the event thread */ 1113 /* Release the event thread */
1078 XSync(SDL_Display, False); 1114 XSync(SDL_Display, False);
1079 SDL_Unlock_EventThread(); 1115 SDL_Unlock_EventThread();
1080 1116
1081 /* We're done! */ 1117 /* We're done! */
1082 return(current); 1118 return (current);
1083 } 1119 }
1084 1120
1085 static int X11_ToggleFullScreen(_THIS, int on) 1121 static int
1086 { 1122 X11_ToggleFullScreen(_THIS, int on)
1087 Uint32 event_thread; 1123 {
1088 1124 Uint32 event_thread;
1089 /* Don't switch if we don't own the window */ 1125
1090 if ( SDL_windowid ) { 1126 /* Don't switch if we don't own the window */
1091 return(0); 1127 if (SDL_windowid) {
1092 } 1128 return (0);
1093 1129 }
1094 /* Don't lock if we are the event thread */ 1130
1095 event_thread = SDL_EventThreadID(); 1131 /* Don't lock if we are the event thread */
1096 if ( event_thread && (SDL_ThreadID() == event_thread) ) { 1132 event_thread = SDL_EventThreadID();
1097 event_thread = 0; 1133 if (event_thread && (SDL_ThreadID() == event_thread)) {
1098 } 1134 event_thread = 0;
1099 if ( event_thread ) { 1135 }
1100 SDL_Lock_EventThread(); 1136 if (event_thread) {
1101 } 1137 SDL_Lock_EventThread();
1102 if ( on ) { 1138 }
1103 this->screen->flags |= SDL_FULLSCREEN; 1139 if (on) {
1104 X11_EnterFullScreen(this); 1140 SDL_VideoSurface->flags |= SDL_FULLSCREEN;
1105 } else { 1141 X11_EnterFullScreen(this);
1106 this->screen->flags &= ~SDL_FULLSCREEN; 1142 } else {
1107 X11_LeaveFullScreen(this); 1143 SDL_VideoSurface->flags &= ~SDL_FULLSCREEN;
1108 } 1144 X11_LeaveFullScreen(this);
1109 X11_RefreshDisplay(this); 1145 }
1110 if ( event_thread ) { 1146 X11_RefreshDisplay(this);
1111 SDL_Unlock_EventThread(); 1147 if (event_thread) {
1112 } 1148 SDL_Unlock_EventThread();
1113 SDL_ResetKeyboard(); 1149 }
1114 return(1); 1150 SDL_ResetKeyboard();
1151 return (1);
1115 } 1152 }
1116 1153
1117 /* Update the current mouse state and position */ 1154 /* Update the current mouse state and position */
1118 static void X11_UpdateMouse(_THIS) 1155 static void
1119 { 1156 X11_UpdateMouse(_THIS)
1120 Window u1; int u2; 1157 {
1121 Window current_win; 1158 Window u1;
1122 int x, y; 1159 int u2;
1123 unsigned int mask; 1160 Window current_win;
1124 1161 int x, y;
1125 /* Lock the event thread, in multi-threading environments */ 1162 unsigned int mask;
1126 SDL_Lock_EventThread(); 1163
1127 if ( XQueryPointer(SDL_Display, SDL_Window, &u1, &current_win, 1164 /* Lock the event thread, in multi-threading environments */
1128 &u2, &u2, &x, &y, &mask) ) { 1165 SDL_Lock_EventThread();
1129 if ( (x >= 0) && (x < SDL_VideoSurface->w) && 1166 if (XQueryPointer(SDL_Display, SDL_Window, &u1, &current_win,
1130 (y >= 0) && (y < SDL_VideoSurface->h) ) { 1167 &u2, &u2, &x, &y, &mask)) {
1131 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); 1168 if ((x >= 0) && (x < SDL_VideoSurface->w) &&
1132 SDL_PrivateMouseMotion(0, 0, x, y); 1169 (y >= 0) && (y < SDL_VideoSurface->h)) {
1133 } else { 1170 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
1134 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); 1171 SDL_PrivateMouseMotion(0, 0, x, y);
1135 } 1172 } else {
1136 } 1173 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
1137 SDL_Unlock_EventThread(); 1174 }
1175 }
1176 SDL_Unlock_EventThread();
1138 } 1177 }
1139 1178
1140 /* simple colour distance metric. Supposed to be better than a plain 1179 /* simple colour distance metric. Supposed to be better than a plain
1141 Euclidian distance anyway. */ 1180 Euclidian distance anyway. */
1142 #define COLOUR_FACTOR 3 1181 #define COLOUR_FACTOR 3
1143 #define LIGHT_FACTOR 1 1182 #define LIGHT_FACTOR 1
1144 #define COLOUR_DIST(r1, g1, b1, r2, g2, b2) \ 1183 #define COLOUR_DIST(r1, g1, b1, r2, g2, b2) \
1145 (COLOUR_FACTOR * (abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)) \ 1184 (COLOUR_FACTOR * (abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)) \
1146 + LIGHT_FACTOR * abs(r1 + g1 + b1 - (r2 + g2 + b2))) 1185 + LIGHT_FACTOR * abs(r1 + g1 + b1 - (r2 + g2 + b2)))
1147 1186
1148 static void allocate_nearest(_THIS, SDL_Color *colors, 1187 static void
1149 SDL_Color *want, int nwant) 1188 allocate_nearest(_THIS, SDL_Color * colors, SDL_Color * want, int nwant)
1150 { 1189 {
1151 /* 1190 /*
1152 * There is no way to know which ones to choose from, so we retrieve 1191 * There is no way to know which ones to choose from, so we retrieve
1153 * the entire colormap and try the nearest possible, until we find one 1192 * the entire colormap and try the nearest possible, until we find one
1154 * that is shared. 1193 * that is shared.
1155 */ 1194 */
1156 XColor all[256]; 1195 XColor all[256];
1157 int i; 1196 int i;
1158 for(i = 0; i < 256; i++) 1197 for (i = 0; i < 256; i++)
1159 all[i].pixel = i; 1198 all[i].pixel = i;
1160 /* 1199 /*
1161 * XQueryColors sets the flags in the XColor struct, so we use 1200 * XQueryColors sets the flags in the XColor struct, so we use
1162 * that to keep track of which colours are available 1201 * that to keep track of which colours are available
1163 */ 1202 */
1164 XQueryColors(GFX_Display, SDL_XColorMap, all, 256); 1203 XQueryColors(GFX_Display, SDL_XColorMap, all, 256);
1165 1204
1166 for(i = 0; i < nwant; i++) { 1205 for (i = 0; i < nwant; i++) {
1167 XColor *c; 1206 XColor *c;
1168 int j; 1207 int j;
1169 int best = 0; 1208 int best = 0;
1170 int mindist = 0x7fffffff; 1209 int mindist = 0x7fffffff;
1171 int ri = want[i].r; 1210 int ri = want[i].r;
1172 int gi = want[i].g; 1211 int gi = want[i].g;
1173 int bi = want[i].b; 1212 int bi = want[i].b;
1174 for(j = 0; j < 256; j++) { 1213 for (j = 0; j < 256; j++) {
1175 int rj, gj, bj, d2; 1214 int rj, gj, bj, d2;
1176 if(!all[j].flags) 1215 if (!all[j].flags)
1177 continue; /* unavailable colour cell */ 1216 continue; /* unavailable colour cell */
1178 rj = all[j].red >> 8; 1217 rj = all[j].red >> 8;
1179 gj = all[j].green >> 8; 1218 gj = all[j].green >> 8;
1180 bj = all[j].blue >> 8; 1219 bj = all[j].blue >> 8;
1181 d2 = COLOUR_DIST(ri, gi, bi, rj, gj, bj); 1220 d2 = COLOUR_DIST(ri, gi, bi, rj, gj, bj);
1182 if(d2 < mindist) { 1221 if (d2 < mindist) {
1183 mindist = d2; 1222 mindist = d2;
1184 best = j; 1223 best = j;
1185 } 1224 }
1186 } 1225 }
1187 if(SDL_XPixels[best]) 1226 if (SDL_XPixels[best])
1188 continue; /* already allocated, waste no more time */ 1227 continue; /* already allocated, waste no more time */
1189 c = all + best; 1228 c = all + best;
1190 if(XAllocColor(GFX_Display, SDL_XColorMap, c)) { 1229 if (XAllocColor(GFX_Display, SDL_XColorMap, c)) {
1191 /* got it */ 1230 /* got it */
1192 colors[c->pixel].r = c->red >> 8; 1231 colors[c->pixel].r = c->red >> 8;
1193 colors[c->pixel].g = c->green >> 8; 1232 colors[c->pixel].g = c->green >> 8;
1194 colors[c->pixel].b = c->blue >> 8; 1233 colors[c->pixel].b = c->blue >> 8;
1195 ++SDL_XPixels[c->pixel]; 1234 ++SDL_XPixels[c->pixel];
1196 } else { 1235 } else {
1197 /* 1236 /*
1198 * The colour couldn't be allocated, probably being 1237 * The colour couldn't be allocated, probably being
1199 * owned as a r/w cell by another client. Flag it as 1238 * owned as a r/w cell by another client. Flag it as
1200 * unavailable and try again. The termination of the 1239 * unavailable and try again. The termination of the
1201 * loop is guaranteed since at least black and white 1240 * loop is guaranteed since at least black and white
1202 * are always there. 1241 * are always there.
1203 */ 1242 */
1204 c->flags = 0; 1243 c->flags = 0;
1205 i--; 1244 i--;
1206 } 1245 }
1207 } 1246 }
1208 } 1247 }
1209 1248
1210 int X11_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 1249 int
1211 { 1250 X11_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
1212 int nrej = 0; 1251 {
1213 1252 int nrej = 0;
1214 /* Check to make sure we have a colormap allocated */ 1253
1215 if ( SDL_XPixels == NULL ) { 1254 /* Check to make sure we have a colormap allocated */
1216 return(0); 1255 if (SDL_XPixels == NULL) {
1217 } 1256 return (0);
1218 if ( (this->screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { 1257 }
1219 /* private writable colormap: just set the colours we need */ 1258 if ((SDL_VideoSurface->flags & SDL_HWPALETTE) == SDL_HWPALETTE) {
1220 XColor *xcmap; 1259 /* private writable colormap: just set the colours we need */
1221 int i; 1260 XColor *xcmap;
1222 xcmap = SDL_stack_alloc(XColor, ncolors); 1261 int i;
1223 if(xcmap == NULL) 1262 xcmap = SDL_stack_alloc(XColor, ncolors);
1224 return 0; 1263 if (xcmap == NULL)
1225 for ( i=0; i<ncolors; ++i ) { 1264 return 0;
1226 xcmap[i].pixel = i + firstcolor; 1265 for (i = 0; i < ncolors; ++i) {
1227 xcmap[i].red = (colors[i].r<<8)|colors[i].r; 1266 xcmap[i].pixel = i + firstcolor;
1228 xcmap[i].green = (colors[i].g<<8)|colors[i].g; 1267 xcmap[i].red = (colors[i].r << 8) | colors[i].r;
1229 xcmap[i].blue = (colors[i].b<<8)|colors[i].b; 1268 xcmap[i].green = (colors[i].g << 8) | colors[i].g;
1230 xcmap[i].flags = (DoRed|DoGreen|DoBlue); 1269 xcmap[i].blue = (colors[i].b << 8) | colors[i].b;
1231 } 1270 xcmap[i].flags = (DoRed | DoGreen | DoBlue);
1232 XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); 1271 }
1233 XSync(GFX_Display, False); 1272 XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors);
1234 SDL_stack_free(xcmap); 1273 XSync(GFX_Display, False);
1235 } else { 1274 SDL_stack_free(xcmap);
1236 /* 1275 } else {
1237 * Shared colormap: We only allocate read-only cells, which 1276 /*
1238 * increases the likelyhood of colour sharing with other 1277 * Shared colormap: We only allocate read-only cells, which
1239 * clients. The pixel values will almost certainly be 1278 * increases the likelyhood of colour sharing with other
1240 * different from the requested ones, so the user has to 1279 * clients. The pixel values will almost certainly be
1241 * walk the colormap and see which index got what colour. 1280 * different from the requested ones, so the user has to
1242 * 1281 * walk the colormap and see which index got what colour.
1243 * We can work directly with the logical palette since it 1282 *
1244 * has already been set when we get here. 1283 * We can work directly with the logical palette since it
1245 */ 1284 * has already been set when we get here.
1246 SDL_Color *want, *reject; 1285 */
1247 unsigned long *freelist; 1286 SDL_Color *want, *reject;
1248 int i; 1287 unsigned long *freelist;
1249 int nfree = 0; 1288 int i;
1250 int nc = this->screen->format->palette->ncolors; 1289 int nfree = 0;
1251 colors = this->screen->format->palette->colors; 1290 int nc = SDL_VideoSurface->format->palette->ncolors;
1252 freelist = SDL_stack_alloc(unsigned long, nc); 1291 colors = SDL_VideoSurface->format->palette->colors;
1253 /* make sure multiple allocations of the same cell are freed */ 1292 freelist = SDL_stack_alloc(unsigned long, nc);
1254 for(i = 0; i < ncolors; i++) { 1293 /* make sure multiple allocations of the same cell are freed */
1255 int pixel = firstcolor + i; 1294 for (i = 0; i < ncolors; i++) {
1256 while(SDL_XPixels[pixel]) { 1295 int pixel = firstcolor + i;
1257 freelist[nfree++] = pixel; 1296 while (SDL_XPixels[pixel]) {
1258 --SDL_XPixels[pixel]; 1297 freelist[nfree++] = pixel;
1259 } 1298 --SDL_XPixels[pixel];
1260 } 1299 }
1261 XFreeColors(GFX_Display, SDL_XColorMap, freelist, nfree, 0); 1300 }
1262 SDL_stack_free(freelist); 1301 XFreeColors(GFX_Display, SDL_XColorMap, freelist, nfree, 0);
1263 1302 SDL_stack_free(freelist);
1264 want = SDL_stack_alloc(SDL_Color, ncolors); 1303
1265 reject = SDL_stack_alloc(SDL_Color, ncolors); 1304 want = SDL_stack_alloc(SDL_Color, ncolors);
1266 SDL_memcpy(want, colors + firstcolor, ncolors * sizeof(SDL_Color)); 1305 reject = SDL_stack_alloc(SDL_Color, ncolors);
1267 /* make sure the user isn't fooled by her own wishes 1306 SDL_memcpy(want, colors + firstcolor, ncolors * sizeof(SDL_Color));
1268 (black is safe, always available in the default colormap) */ 1307 /* make sure the user isn't fooled by her own wishes
1269 SDL_memset(colors + firstcolor, 0, ncolors * sizeof(SDL_Color)); 1308 (black is safe, always available in the default colormap) */
1270 1309 SDL_memset(colors + firstcolor, 0, ncolors * sizeof(SDL_Color));
1271 /* now try to allocate the colours */ 1310
1272 for(i = 0; i < ncolors; i++) { 1311 /* now try to allocate the colours */
1273 XColor col; 1312 for (i = 0; i < ncolors; i++) {
1274 col.red = want[i].r << 8; 1313 XColor col;
1275 col.green = want[i].g << 8; 1314 col.red = want[i].r << 8;
1276 col.blue = want[i].b << 8; 1315 col.green = want[i].g << 8;
1277 col.flags = DoRed | DoGreen | DoBlue; 1316 col.blue = want[i].b << 8;
1278 if(XAllocColor(GFX_Display, SDL_XColorMap, &col)) { 1317 col.flags = DoRed | DoGreen | DoBlue;
1279 /* We got the colour, or at least the nearest 1318 if (XAllocColor(GFX_Display, SDL_XColorMap, &col)) {
1280 the hardware could get. */ 1319 /* We got the colour, or at least the nearest
1281 colors[col.pixel].r = col.red >> 8; 1320 the hardware could get. */
1282 colors[col.pixel].g = col.green >> 8; 1321 colors[col.pixel].r = col.red >> 8;
1283 colors[col.pixel].b = col.blue >> 8; 1322 colors[col.pixel].g = col.green >> 8;
1284 ++SDL_XPixels[col.pixel]; 1323 colors[col.pixel].b = col.blue >> 8;
1285 } else { 1324 ++SDL_XPixels[col.pixel];
1286 /* 1325 } else {
1287 * no more free cells, add it to the list 1326 /*
1288 * of rejected colours 1327 * no more free cells, add it to the list
1289 */ 1328 * of rejected colours
1290 reject[nrej++] = want[i]; 1329 */
1291 } 1330 reject[nrej++] = want[i];
1292 } 1331 }
1293 if(nrej) 1332 }
1294 allocate_nearest(this, colors, reject, nrej); 1333 if (nrej)
1295 SDL_stack_free(reject); 1334 allocate_nearest(this, colors, reject, nrej);
1296 SDL_stack_free(want); 1335 SDL_stack_free(reject);
1297 } 1336 SDL_stack_free(want);
1298 return nrej == 0; 1337 }
1299 } 1338 return nrej == 0;
1300 1339 }
1301 int X11_SetGammaRamp(_THIS, Uint16 *ramp) 1340
1302 { 1341 int
1303 int i, ncolors; 1342 X11_SetGammaRamp(_THIS, Uint16 * ramp)
1304 XColor xcmap[256]; 1343 {
1305 1344 int i, ncolors;
1306 /* See if actually setting the gamma is supported */ 1345 XColor xcmap[256];
1307 if ( SDL_Visual->class != DirectColor ) { 1346
1308 SDL_SetError("Gamma correction not supported on this visual"); 1347 /* See if actually setting the gamma is supported */
1309 return(-1); 1348 if (SDL_Visual->class != DirectColor) {
1310 } 1349 SDL_SetError("Gamma correction not supported on this visual");
1311 1350 return (-1);
1312 /* Calculate the appropriate palette for the given gamma ramp */ 1351 }
1313 ncolors = SDL_Visual->map_entries; 1352
1314 for ( i=0; i<ncolors; ++i ) { 1353 /* Calculate the appropriate palette for the given gamma ramp */
1315 Uint8 c = (256 * i / ncolors); 1354 ncolors = SDL_Visual->map_entries;
1316 xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c); 1355 for (i = 0; i < ncolors; ++i) {
1317 xcmap[i].red = ramp[0*256+c]; 1356 Uint8 c = (256 * i / ncolors);
1318 xcmap[i].green = ramp[1*256+c]; 1357 xcmap[i].pixel = SDL_MapRGB(SDL_VideoSurface->format, c, c, c);
1319 xcmap[i].blue = ramp[2*256+c]; 1358 xcmap[i].red = ramp[0 * 256 + c];
1320 xcmap[i].flags = (DoRed|DoGreen|DoBlue); 1359 xcmap[i].green = ramp[1 * 256 + c];
1321 } 1360 xcmap[i].blue = ramp[2 * 256 + c];
1322 XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); 1361 xcmap[i].flags = (DoRed | DoGreen | DoBlue);
1323 XSync(GFX_Display, False); 1362 }
1324 return(0); 1363 XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors);
1364 XSync(GFX_Display, False);
1365 return (0);
1325 } 1366 }
1326 1367
1327 /* Note: If we are terminated, this could be called in the middle of 1368 /* Note: If we are terminated, this could be called in the middle of
1328 another SDL video routine -- notably UpdateRects. 1369 another SDL video routine -- notably UpdateRects.
1329 */ 1370 */
1330 void X11_VideoQuit(_THIS) 1371 void
1331 { 1372 X11_VideoQuit(_THIS)
1332 /* Shutdown everything that's still up */ 1373 {
1333 /* The event thread should be done, so we can touch SDL_Display */ 1374 /* Shutdown everything that's still up */
1334 if ( SDL_Display != NULL ) { 1375 /* The event thread should be done, so we can touch SDL_Display */
1335 /* Flush any delayed updates */ 1376 if (SDL_Display != NULL) {
1336 XSync(GFX_Display, False); 1377 /* Flush any delayed updates */
1337 1378 XSync(GFX_Display, False);
1338 /* Close the connection with the IM server */ 1379
1339 #ifdef X_HAVE_UTF8_STRING 1380 /* Close the connection with the IM server */
1340 if (SDL_IC != NULL) { 1381 #ifdef X_HAVE_UTF8_STRING
1341 XDestroyIC(SDL_IC); 1382 if (SDL_IC != NULL) {
1342 SDL_IC = NULL; 1383 XDestroyIC(SDL_IC);
1343 } 1384 SDL_IC = NULL;
1344 if (SDL_IM != NULL) { 1385 }
1345 XCloseIM(SDL_IM); 1386 if (SDL_IM != NULL) {
1346 SDL_IM = NULL; 1387 XCloseIM(SDL_IM);
1347 } 1388 SDL_IM = NULL;
1348 #endif 1389 }
1349 1390 #endif
1350 /* Start shutting down the windows */ 1391
1351 X11_DestroyImage(this, this->screen); 1392 /* Start shutting down the windows */
1352 X11_DestroyWindow(this, this->screen); 1393 X11_DestroyImage(this, SDL_VideoSurface);
1353 X11_FreeVideoModes(this); 1394 X11_DestroyWindow(this, SDL_VideoSurface);
1354 if ( SDL_XColorMap != SDL_DisplayColormap ) { 1395 X11_FreeVideoModes(this);
1355 XFreeColormap(SDL_Display, SDL_XColorMap); 1396 if (SDL_XColorMap != SDL_DisplayColormap) {
1356 } 1397 XFreeColormap(SDL_Display, SDL_XColorMap);
1357 if ( SDL_iconcolors ) { 1398 }
1358 unsigned long pixel; 1399 if (SDL_iconcolors) {
1359 Colormap dcmap = DefaultColormap(SDL_Display, 1400 unsigned long pixel;
1360 SDL_Screen); 1401 Colormap dcmap = DefaultColormap(SDL_Display,
1361 for(pixel = 0; pixel < 256; ++pixel) { 1402 SDL_Screen);
1362 while(SDL_iconcolors[pixel] > 0) { 1403 for (pixel = 0; pixel < 256; ++pixel) {
1363 XFreeColors(GFX_Display, 1404 while (SDL_iconcolors[pixel] > 0) {
1364 dcmap, &pixel, 1, 0); 1405 XFreeColors(GFX_Display, dcmap, &pixel, 1, 0);
1365 --SDL_iconcolors[pixel]; 1406 --SDL_iconcolors[pixel];
1366 } 1407 }
1367 } 1408 }
1368 SDL_free(SDL_iconcolors); 1409 SDL_free(SDL_iconcolors);
1369 SDL_iconcolors = NULL; 1410 SDL_iconcolors = NULL;
1370 } 1411 }
1371 1412 if (xinerama) {
1372 /* Restore gamma settings if they've changed */ 1413 XFree(xinerama);
1373 if ( SDL_GetAppState() & SDL_APPACTIVE ) { 1414 }
1374 X11_SwapVidModeGamma(this); 1415
1375 } 1416 /* Restore gamma settings if they've changed */
1376 1417 if (SDL_GetAppState() & SDL_APPACTIVE) {
1377 /* Restore DPMS and screensaver settings */ 1418 X11_SwapVidModeGamma(this);
1378 X11_RestoreScreenSaver(SDL_Display, screensaver_timeout, dpms_enabled); 1419 }
1379 1420
1380 /* Free that blank cursor */ 1421 /* Restore DPMS and screensaver settings */
1381 if ( SDL_BlankCursor != NULL ) { 1422 X11_RestoreScreenSaver(SDL_Display, screensaver_timeout,
1382 this->FreeWMCursor(this, SDL_BlankCursor); 1423 dpms_enabled);
1383 SDL_BlankCursor = NULL; 1424
1384 } 1425 /* Free that blank cursor */
1385 1426 if (SDL_BlankCursor != NULL) {
1386 /* Close the X11 graphics connection */ 1427 this->FreeWMCursor(this, SDL_BlankCursor);
1387 if ( GFX_Display != NULL ) { 1428 SDL_BlankCursor = NULL;
1388 XCloseDisplay(GFX_Display); 1429 }
1389 GFX_Display = NULL; 1430
1390 } 1431 /* Close the X11 graphics connection */
1391 1432 if (GFX_Display != NULL) {
1392 /* Close the X11 display connection */ 1433 XCloseDisplay(GFX_Display);
1393 XCloseDisplay(SDL_Display); 1434 GFX_Display = NULL;
1394 SDL_Display = NULL; 1435 }
1395 1436
1396 /* Reset the X11 error handlers */ 1437 /* Close the X11 display connection */
1397 if ( XIO_handler ) { 1438 XCloseDisplay(SDL_Display);
1398 XSetIOErrorHandler(XIO_handler); 1439 SDL_Display = NULL;
1399 } 1440
1400 if ( X_handler ) { 1441 /* Reset the X11 error handlers */
1401 XSetErrorHandler(X_handler); 1442 if (XIO_handler) {
1402 } 1443 XSetIOErrorHandler(XIO_handler);
1403 1444 }
1404 /* Unload GL library after X11 shuts down */ 1445 if (X_handler) {
1405 X11_GL_UnloadLibrary(this); 1446 XSetErrorHandler(X_handler);
1406 } 1447 }
1407 if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { 1448
1408 /* Direct screen access, no memory buffer */ 1449 /* Unload GL library after X11 shuts down */
1409 this->screen->pixels = NULL; 1450 X11_GL_UnloadLibrary(this);
1410 } 1451 }
1411 } 1452 if (SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_HWSURFACE)) {
1412 1453 /* Direct screen access, no memory buffer */
1454 SDL_VideoSurface->pixels = NULL;
1455 }
1456 }
1457
1458 /* vi: set ts=4 sw=4 expandtab: */