comparison src/video/x11/SDL_x11wm.c @ 1575:3ba88cb7eb1b

Updated dynamic X11 code. See details in Bugzilla #170.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 22 Mar 2006 05:00:59 +0000
parents b46bb79cc197
children 14717b52abc0 c2c6ff414ef5
comparison
equal deleted inserted replaced
1574:0fd72308659e 1575:3ba88cb7eb1b
114 while(SDL_iconcolors[i]) { 114 while(SDL_iconcolors[i]) {
115 freelist[nfree++] = i; 115 freelist[nfree++] = i;
116 SDL_iconcolors[i]--; 116 SDL_iconcolors[i]--;
117 } 117 }
118 } 118 }
119 pXFreeColors(GFX_Display, dcmap, freelist, nfree, 0); 119 XFreeColors(GFX_Display, dcmap, freelist, nfree, 0);
120 } 120 }
121 if(!SDL_iconcolors) 121 if(!SDL_iconcolors)
122 SDL_iconcolors = SDL_malloc(256 * sizeof *SDL_iconcolors); 122 SDL_iconcolors = SDL_malloc(256 * sizeof *SDL_iconcolors);
123 SDL_memset(SDL_iconcolors, 0, 256 * sizeof *SDL_iconcolors); 123 SDL_memset(SDL_iconcolors, 0, 256 * sizeof *SDL_iconcolors);
124 124
129 XColor c; 129 XColor c;
130 c.red = want[i].r << 8; 130 c.red = want[i].r << 8;
131 c.green = want[i].g << 8; 131 c.green = want[i].g << 8;
132 c.blue = want[i].b << 8; 132 c.blue = want[i].b << 8;
133 c.flags = DoRed | DoGreen | DoBlue; 133 c.flags = DoRed | DoGreen | DoBlue;
134 if(pXAllocColor(GFX_Display, dcmap, &c)) { 134 if(XAllocColor(GFX_Display, dcmap, &c)) {
135 /* got the colour */ 135 /* got the colour */
136 SDL_iconcolors[c.pixel]++; 136 SDL_iconcolors[c.pixel]++;
137 got[c.pixel] = want[i]; 137 got[c.pixel] = want[i];
138 } else { 138 } else {
139 missing = 1; 139 missing = 1;
143 /* Some colours were apparently missing, so we just 143 /* Some colours were apparently missing, so we just
144 allocate all the rest as well */ 144 allocate all the rest as well */
145 XColor cols[256]; 145 XColor cols[256];
146 for(i = 0; i < 256; i++) 146 for(i = 0; i < 256; i++)
147 cols[i].pixel = i; 147 cols[i].pixel = i;
148 pXQueryColors(GFX_Display, dcmap, cols, 256); 148 XQueryColors(GFX_Display, dcmap, cols, 256);
149 for(i = 0; i < 256; i++) { 149 for(i = 0; i < 256; i++) {
150 got[i].r = cols[i].red >> 8; 150 got[i].r = cols[i].red >> 8;
151 got[i].g = cols[i].green >> 8; 151 got[i].g = cols[i].green >> 8;
152 got[i].b = cols[i].blue >> 8; 152 got[i].b = cols[i].blue >> 8;
153 if(!SDL_iconcolors[i]) { 153 if(!SDL_iconcolors[i]) {
154 if(pXAllocColor(GFX_Display, dcmap, 154 if(XAllocColor(GFX_Display, dcmap,
155 cols + i)) { 155 cols + i)) {
156 SDL_iconcolors[i] = 1; 156 SDL_iconcolors[i] = 1;
157 } else { 157 } else {
158 /* index not available */ 158 /* index not available */
159 got[i].r = 0; 159 got[i].r = 0;
182 goto done; 182 goto done;
183 } 183 }
184 SDL_memset(LSBmask, 0, masksize); 184 SDL_memset(LSBmask, 0, masksize);
185 for(i = 0; i < masksize; i++) 185 for(i = 0; i < masksize; i++)
186 LSBmask[i] = reverse_byte(mask[i]); 186 LSBmask[i] = reverse_byte(mask[i]);
187 mask_pixmap = pXCreatePixmapFromBitmapData(SDL_Display, WMwindow, 187 mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow,
188 (char *)LSBmask, 188 (char *)LSBmask,
189 sicon->w, sicon->h, 189 sicon->w, sicon->h,
190 1L, 0L, 1); 190 1L, 0L, 1);
191 191
192 /* Transfer the image to an X11 pixmap */ 192 /* Transfer the image to an X11 pixmap */
193 icon_image = pXCreateImage(SDL_Display, 193 icon_image = XCreateImage(SDL_Display,
194 DefaultVisual(SDL_Display, SDL_Screen), 194 DefaultVisual(SDL_Display, SDL_Screen),
195 DefaultDepth(SDL_Display, SDL_Screen), 195 DefaultDepth(SDL_Display, SDL_Screen),
196 ZPixmap, 0, sicon->pixels, 196 ZPixmap, 0, sicon->pixels,
197 sicon->w, sicon->h, 197 sicon->w, sicon->h,
198 32, 0); 198 32, 0);
199 icon_image->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) 199 icon_image->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN)
200 ? MSBFirst : LSBFirst; 200 ? MSBFirst : LSBFirst;
201 icon_pixmap = pXCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h, 201 icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h,
202 DefaultDepth(SDL_Display, SDL_Screen)); 202 DefaultDepth(SDL_Display, SDL_Screen));
203 gc = pXCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues); 203 gc = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues);
204 pXPutImage(SDL_Display, icon_pixmap, gc, icon_image, 204 XPutImage(SDL_Display, icon_pixmap, gc, icon_image,
205 0, 0, 0, 0, sicon->w, sicon->h); 205 0, 0, 0, 0, sicon->w, sicon->h);
206 pXFreeGC(SDL_Display, gc); 206 XFreeGC(SDL_Display, gc);
207 pXDestroyImage(icon_image); 207 XDestroyImage(icon_image);
208 SDL_free(LSBmask); 208 SDL_free(LSBmask);
209 sicon->pixels = NULL; 209 sicon->pixels = NULL;
210 210
211 /* Some buggy window managers (some versions of Enlightenment, it 211 /* Some buggy window managers (some versions of Enlightenment, it
212 seems) need an icon window *and* icon pixmap to work properly, while 212 seems) need an icon window *and* icon pixmap to work properly, while
213 it screws up others. The default is only to use a pixmap. */ 213 it screws up others. The default is only to use a pixmap. */
214 p = SDL_getenv("SDL_VIDEO_X11_ICONWIN"); 214 p = SDL_getenv("SDL_VIDEO_X11_ICONWIN");
215 if(p && *p) { 215 if(p && *p) {
216 icon_window = pXCreateSimpleWindow(SDL_Display, SDL_Root, 216 icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root,
217 0, 0, sicon->w, sicon->h, 0, 217 0, 0, sicon->w, sicon->h, 0,
218 CopyFromParent, 218 CopyFromParent,
219 CopyFromParent); 219 CopyFromParent);
220 pXSetWindowBackgroundPixmap(SDL_Display, icon_window, 220 XSetWindowBackgroundPixmap(SDL_Display, icon_window,
221 icon_pixmap); 221 icon_pixmap);
222 pXClearWindow(SDL_Display, icon_window); 222 XClearWindow(SDL_Display, icon_window);
223 } 223 }
224 224
225 /* Set the window icon to the icon pixmap (and icon window) */ 225 /* Set the window icon to the icon pixmap (and icon window) */
226 wmhints = pXAllocWMHints(); 226 wmhints = XAllocWMHints();
227 wmhints->flags = (IconPixmapHint | IconMaskHint); 227 wmhints->flags = (IconPixmapHint | IconMaskHint);
228 wmhints->icon_pixmap = icon_pixmap; 228 wmhints->icon_pixmap = icon_pixmap;
229 wmhints->icon_mask = mask_pixmap; 229 wmhints->icon_mask = mask_pixmap;
230 if(icon_window != None) { 230 if(icon_window != None) {
231 wmhints->flags |= IconWindowHint; 231 wmhints->flags |= IconWindowHint;
232 wmhints->icon_window = icon_window; 232 wmhints->icon_window = icon_window;
233 } 233 }
234 pXSetWMHints(SDL_Display, WMwindow, wmhints); 234 XSetWMHints(SDL_Display, WMwindow, wmhints);
235 pXFree(wmhints); 235 XFree(wmhints);
236 pXSync(SDL_Display, False); 236 XSync(SDL_Display, False);
237 237
238 done: 238 done:
239 SDL_Unlock_EventThread(); 239 SDL_Unlock_EventThread();
240 SDL_FreeSurface(sicon); 240 SDL_FreeSurface(sicon);
241 } 241 }
248 #ifdef X_HAVE_UTF8_STRING 248 #ifdef X_HAVE_UTF8_STRING
249 Atom _NET_WM_NAME; 249 Atom _NET_WM_NAME;
250 Atom _NET_WM_ICON_NAME; 250 Atom _NET_WM_ICON_NAME;
251 251
252 /* Look up some useful Atoms */ 252 /* Look up some useful Atoms */
253 _NET_WM_NAME = pXInternAtom(SDL_Display, "_NET_WM_NAME", False); 253 if (SDL_X11_HAVE_UTF8) {
254 _NET_WM_ICON_NAME = pXInternAtom(SDL_Display, "_NET_WM_ICON_NAME", False); 254 _NET_WM_NAME = XInternAtom(SDL_Display, "_NET_WM_NAME", False);
255 _NET_WM_ICON_NAME = XInternAtom(SDL_Display, "_NET_WM_ICON_NAME", False);
256 }
255 #endif 257 #endif
256 258
257 /* Lock the event thread, in multi-threading environments */ 259 /* Lock the event thread, in multi-threading environments */
258 SDL_Lock_EventThread(); 260 SDL_Lock_EventThread();
259 261
261 char *title_latin1 = SDL_iconv_utf8_latin1((char *)title); 263 char *title_latin1 = SDL_iconv_utf8_latin1((char *)title);
262 if ( !title_latin1 ) { 264 if ( !title_latin1 ) {
263 SDL_OutOfMemory(); 265 SDL_OutOfMemory();
264 return; 266 return;
265 } 267 }
266 status = pXStringListToTextProperty(&title_latin1, 1, &titleprop); 268 status = XStringListToTextProperty(&title_latin1, 1, &titleprop);
267 SDL_free(title_latin1); 269 SDL_free(title_latin1);
268 if ( status ) { 270 if ( status ) {
269 pXSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME); 271 XSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME);
270 pXFree(titleprop.value); 272 XFree(titleprop.value);
271 } 273 }
272 #ifdef X_HAVE_UTF8_STRING 274 #ifdef X_HAVE_UTF8_STRING
273 status = pXutf8TextListToTextProperty(SDL_Display, 275 if (SDL_X11_HAVE_UTF8) {
274 (char **)&title, 1, XUTF8StringStyle, &titleprop); 276 status = Xutf8TextListToTextProperty(SDL_Display,
275 if ( status == Success ) { 277 (char **)&title, 1, XUTF8StringStyle, &titleprop);
276 pXSetTextProperty(SDL_Display, WMwindow, &titleprop, _NET_WM_NAME); 278 if ( status == Success ) {
277 pXFree(titleprop.value); 279 XSetTextProperty(SDL_Display, WMwindow, &titleprop, _NET_WM_NAME);
280 XFree(titleprop.value);
281 }
278 } 282 }
279 #endif 283 #endif
280 } 284 }
281 if ( icon != NULL ) { 285 if ( icon != NULL ) {
282 char *icon_latin1 = SDL_iconv_utf8_latin1((char *)icon); 286 char *icon_latin1 = SDL_iconv_utf8_latin1((char *)icon);
283 if ( !icon_latin1 ) { 287 if ( !icon_latin1 ) {
284 SDL_OutOfMemory(); 288 SDL_OutOfMemory();
285 return; 289 return;
286 } 290 }
287 status = pXStringListToTextProperty(&icon_latin1, 1, &iconprop); 291 status = XStringListToTextProperty(&icon_latin1, 1, &iconprop);
288 SDL_free(icon_latin1); 292 SDL_free(icon_latin1);
289 if ( status ) { 293 if ( status ) {
290 pXSetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME); 294 XSetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME);
291 pXFree(iconprop.value); 295 XFree(iconprop.value);
292 } 296 }
293 #ifdef X_HAVE_UTF8_STRING 297 #ifdef X_HAVE_UTF8_STRING
294 status = pXutf8TextListToTextProperty(SDL_Display, 298 if (SDL_X11_HAVE_UTF8) {
295 (char **)&icon, 1, XUTF8StringStyle, &iconprop); 299 status = Xutf8TextListToTextProperty(SDL_Display,
296 if ( status == Success ) { 300 (char **)&icon, 1, XUTF8StringStyle, &iconprop);
297 pXSetTextProperty(SDL_Display, WMwindow, &iconprop, _NET_WM_ICON_NAME); 301 if ( status == Success ) {
298 pXFree(iconprop.value); 302 XSetTextProperty(SDL_Display, WMwindow, &iconprop, _NET_WM_ICON_NAME);
303 XFree(iconprop.value);
304 }
299 } 305 }
300 #endif 306 #endif
301 } 307 }
302 pXSync(SDL_Display, False); 308 XSync(SDL_Display, False);
303 309
304 SDL_Unlock_EventThread(); 310 SDL_Unlock_EventThread();
305 } 311 }
306 312
307 /* Iconify the window */ 313 /* Iconify the window */
308 int X11_IconifyWindow(_THIS) 314 int X11_IconifyWindow(_THIS)
309 { 315 {
310 int result; 316 int result;
311 317
312 SDL_Lock_EventThread(); 318 SDL_Lock_EventThread();
313 result = pXIconifyWindow(SDL_Display, WMwindow, SDL_Screen); 319 result = XIconifyWindow(SDL_Display, WMwindow, SDL_Screen);
314 pXSync(SDL_Display, False); 320 XSync(SDL_Display, False);
315 SDL_Unlock_EventThread(); 321 SDL_Unlock_EventThread();
316 return(result); 322 return(result);
317 } 323 }
318 324
319 SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode) 325 SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode)
325 } 331 }
326 if ( ! SDL_Window ) { 332 if ( ! SDL_Window ) {
327 return(mode); /* Will be set later on mode switch */ 333 return(mode); /* Will be set later on mode switch */
328 } 334 }
329 if ( mode == SDL_GRAB_OFF ) { 335 if ( mode == SDL_GRAB_OFF ) {
330 pXUngrabPointer(SDL_Display, CurrentTime); 336 XUngrabPointer(SDL_Display, CurrentTime);
331 pXUngrabKeyboard(SDL_Display, CurrentTime); 337 XUngrabKeyboard(SDL_Display, CurrentTime);
332 } else { 338 } else {
333 if ( this->screen->flags & SDL_FULLSCREEN ) { 339 if ( this->screen->flags & SDL_FULLSCREEN ) {
334 /* Unbind the mouse from the fullscreen window */ 340 /* Unbind the mouse from the fullscreen window */
335 pXUngrabPointer(SDL_Display, CurrentTime); 341 XUngrabPointer(SDL_Display, CurrentTime);
336 } 342 }
337 /* Try to grab the mouse */ 343 /* Try to grab the mouse */
338 #if 0 /* We'll wait here until we actually grab, otherwise behavior undefined */ 344 #if 0 /* We'll wait here until we actually grab, otherwise behavior undefined */
339 for ( numtries = 0; numtries < 10; ++numtries ) { 345 for ( numtries = 0; numtries < 10; ++numtries ) {
340 #else 346 #else
341 while ( 1 ) { 347 while ( 1 ) {
342 #endif 348 #endif
343 result = pXGrabPointer(SDL_Display, SDL_Window, True, 0, 349 result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
344 GrabModeAsync, GrabModeAsync, 350 GrabModeAsync, GrabModeAsync,
345 SDL_Window, None, CurrentTime); 351 SDL_Window, None, CurrentTime);
346 if ( result == GrabSuccess ) { 352 if ( result == GrabSuccess ) {
347 break; 353 break;
348 } 354 }
350 } 356 }
351 if ( result != GrabSuccess ) { 357 if ( result != GrabSuccess ) {
352 /* Uh, oh, what do we do here? */ ; 358 /* Uh, oh, what do we do here? */ ;
353 } 359 }
354 /* Now grab the keyboard */ 360 /* Now grab the keyboard */
355 pXGrabKeyboard(SDL_Display, WMwindow, True, 361 XGrabKeyboard(SDL_Display, WMwindow, True,
356 GrabModeAsync, GrabModeAsync, CurrentTime); 362 GrabModeAsync, GrabModeAsync, CurrentTime);
357 363
358 /* Raise the window if we grab the mouse */ 364 /* Raise the window if we grab the mouse */
359 if ( !(this->screen->flags & SDL_FULLSCREEN) ) 365 if ( !(this->screen->flags & SDL_FULLSCREEN) )
360 pXRaiseWindow(SDL_Display, WMwindow); 366 XRaiseWindow(SDL_Display, WMwindow);
361 367
362 /* Make sure we register input focus */ 368 /* Make sure we register input focus */
363 SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); 369 SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
364 } 370 }
365 pXSync(SDL_Display, False); 371 XSync(SDL_Display, False);
366 372
367 return(mode); 373 return(mode);
368 } 374 }
369 375
370 SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode) 376 SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode)
385 } 391 }
386 static void unlock_display(void) 392 static void unlock_display(void)
387 { 393 {
388 /* Make sure any X11 transactions are completed */ 394 /* Make sure any X11 transactions are completed */
389 SDL_VideoDevice *this = current_video; 395 SDL_VideoDevice *this = current_video;
390 pXSync(SDL_Display, False); 396 XSync(SDL_Display, False);
391 SDL_Unlock_EventThread(); 397 SDL_Unlock_EventThread();
392 } 398 }
393 int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info) 399 int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info)
394 { 400 {
395 if ( info->version.major <= SDL_MAJOR_VERSION ) { 401 if ( info->version.major <= SDL_MAJOR_VERSION ) {