Mercurial > sdl-ios-xcode
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, ¤t_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, ¤t_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: */ |