comparison src/video/x11/SDL_x11video.c @ 1325:1dfc85090d07

Resolve bug #120 Use the real executable's name for the window class, if it's available.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 03 Feb 2006 07:39:02 +0000
parents 66f6c64c2c69
children d12a63a8d95a
comparison
equal deleted inserted replaced
1324:42e95163d553 1325:1dfc85090d07
277 277
278 /* Everything else goes to the default handler... */ 278 /* Everything else goes to the default handler... */
279 return Xext_handler(d, ext_name, reason); 279 return Xext_handler(d, ext_name, reason);
280 } 280 }
281 281
282 /* Find out what class name we should use */
283 static char *get_classname(char *classname, int maxlen)
284 {
285 char *spot;
286 #if defined(linux) || defined(__FreeBSD__)
287 char procfile[1024];
288 char linkfile[1024];
289 int linksize;
290 #endif
291
292 /* First allow environment variable override */
293 spot = getenv("SDL_VIDEO_X11_WMCLASS");
294 if ( spot ) {
295 strncpy(classname, spot, maxlen);
296 return classname;
297 }
298
299 /* Next look at the application's executable name */
300 #if defined(linux) || defined(__FreeBSD__)
301 #if defined(linux)
302 sprintf(procfile, "/proc/%d/exe", getpid());
303 #elif defined(__FreeBSD__)
304 sprintf(procfile, "/proc/%d/file", getpid());
305 #else
306 #error Where can we find the executable name?
307 #endif
308 linksize = readlink(procfile, linkfile, sizeof(linkfile)-1);
309 if ( linksize > 0 ) {
310 linkfile[linksize] = '\0';
311 spot = strrchr(linkfile, '/');
312 if ( spot ) {
313 strncpy(classname, spot+1, maxlen);
314 } else {
315 strncpy(classname, linkfile, maxlen);
316 }
317 return classname;
318 }
319 #endif /* linux */
320
321 /* Finally use the default we've used forever */
322 strncpy(classname, "SDL_App", maxlen);
323 return classname;
324 }
325
282 /* Create auxiliary (toplevel) windows with the current visual */ 326 /* Create auxiliary (toplevel) windows with the current visual */
283 static void create_aux_windows(_THIS) 327 static void create_aux_windows(_THIS)
284 { 328 {
285 char * savedclassname = NULL; 329 char classname[1024];
286 XSetWindowAttributes xattr; 330 XSetWindowAttributes xattr;
287 XWMHints *hints; 331 XWMHints *hints;
288 XTextProperty titleprop, iconprop; 332 XTextProperty titleprop, iconprop;
289 int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen)); 333 int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));
290 334
366 pXSelectInput(SDL_Display, WMwindow, 410 pXSelectInput(SDL_Display, WMwindow,
367 FocusChangeMask | KeyPressMask | KeyReleaseMask 411 FocusChangeMask | KeyPressMask | KeyReleaseMask
368 | PropertyChangeMask | StructureNotifyMask | KeymapStateMask); 412 | PropertyChangeMask | StructureNotifyMask | KeymapStateMask);
369 413
370 /* Set the class hints so we can get an icon (AfterStep) */ 414 /* Set the class hints so we can get an icon (AfterStep) */
415 get_classname(classname, sizeof(classname));
371 { 416 {
372 XClassHint *classhints; 417 XClassHint *classhints;
373 classhints = pXAllocClassHint(); 418 classhints = pXAllocClassHint();
374 if(classhints != NULL) { 419 if(classhints != NULL) {
375 char *classname = getenv("SDL_VIDEO_X11_WMCLASS");
376 if ( ! classname ) {
377 classname = "SDL_App";
378 }
379 savedclassname = strdup(classname);
380 classhints->res_name = classname; 420 classhints->res_name = classname;
381 classhints->res_class = classname; 421 classhints->res_class = classname;
382 pXSetClassHint(SDL_Display, WMwindow, classhints); 422 pXSetClassHint(SDL_Display, WMwindow, classhints);
383 pXFree(classhints); 423 pXFree(classhints);
384 } 424 }
387 /* Setup the communication with the IM server */ 427 /* Setup the communication with the IM server */
388 SDL_IM = NULL; 428 SDL_IM = NULL;
389 SDL_IC = NULL; 429 SDL_IC = NULL;
390 430
391 #ifdef X_HAVE_UTF8_STRING 431 #ifdef X_HAVE_UTF8_STRING
392 SDL_IM = pXOpenIM(SDL_Display, NULL, savedclassname, savedclassname); 432 SDL_IM = pXOpenIM(SDL_Display, NULL, classname, classname);
393 if (SDL_IM == NULL) { 433 if (SDL_IM == NULL) {
394 SDL_SetError("no input method could be opened"); 434 SDL_SetError("no input method could be opened");
395 } else { 435 } else {
396 SDL_IC = pXCreateIC(SDL_IM, 436 SDL_IC = pXCreateIC(SDL_IM,
397 XNClientWindow, WMwindow, 437 XNClientWindow, WMwindow,
398 XNFocusWindow, WMwindow, 438 XNFocusWindow, WMwindow,
399 XNInputStyle, XIMPreeditNothing | XIMStatusNothing, 439 XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
400 XNResourceName, savedclassname, 440 XNResourceName, classname,
401 XNResourceClass, savedclassname, 441 XNResourceClass, classname,
402 NULL); 442 NULL);
403 if (SDL_IC == NULL) { 443 if (SDL_IC == NULL) {
404 SDL_SetError("no input context could be created"); 444 SDL_SetError("no input context could be created");
405 pXCloseIM(SDL_IM); 445 pXCloseIM(SDL_IM);
406 SDL_IM = NULL; 446 SDL_IM = NULL;
407 } 447 }
408 } 448 }
409 #endif 449 #endif
410
411 free(savedclassname);
412
413 450
414 /* Allow the window to be deleted by the window manager */ 451 /* Allow the window to be deleted by the window manager */
415 WM_DELETE_WINDOW = pXInternAtom(SDL_Display, "WM_DELETE_WINDOW", False); 452 WM_DELETE_WINDOW = pXInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
416 pXSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1); 453 pXSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);
417 } 454 }