Resolve bug #120
authorSam Lantinga <slouken@libsdl.org>
Fri, 03 Feb 2006 07:39:02 +0000
changeset 13251dfc85090d07
parent 1324 42e95163d553
child 1326 9439c2f1da89
Resolve bug #120
Use the real executable's name for the window class, if it's available.
src/video/x11/SDL_x11video.c
     1.1 --- a/src/video/x11/SDL_x11video.c	Fri Feb 03 06:33:54 2006 +0000
     1.2 +++ b/src/video/x11/SDL_x11video.c	Fri Feb 03 07:39:02 2006 +0000
     1.3 @@ -279,10 +279,54 @@
     1.4  	return Xext_handler(d, ext_name, reason);
     1.5  }
     1.6  
     1.7 +/* Find out what class name we should use */
     1.8 +static char *get_classname(char *classname, int maxlen)
     1.9 +{
    1.10 +	char *spot;
    1.11 +#if defined(linux) || defined(__FreeBSD__)
    1.12 +	char procfile[1024];
    1.13 +	char linkfile[1024];
    1.14 +	int linksize;
    1.15 +#endif
    1.16 +
    1.17 +	/* First allow environment variable override */
    1.18 +	spot = getenv("SDL_VIDEO_X11_WMCLASS");
    1.19 +	if ( spot ) {
    1.20 +		strncpy(classname, spot, maxlen);
    1.21 +		return classname;
    1.22 +	}
    1.23 +
    1.24 +	/* Next look at the application's executable name */
    1.25 +#if defined(linux) || defined(__FreeBSD__)
    1.26 +#if defined(linux)
    1.27 +	sprintf(procfile, "/proc/%d/exe", getpid());
    1.28 +#elif defined(__FreeBSD__)
    1.29 +	sprintf(procfile, "/proc/%d/file", getpid());
    1.30 +#else
    1.31 +#error Where can we find the executable name?
    1.32 +#endif
    1.33 +	linksize = readlink(procfile, linkfile, sizeof(linkfile)-1);
    1.34 +	if ( linksize > 0 ) {
    1.35 +		linkfile[linksize] = '\0';
    1.36 +		spot = strrchr(linkfile, '/');
    1.37 +		if ( spot ) {
    1.38 +			strncpy(classname, spot+1, maxlen);
    1.39 +		} else {
    1.40 +			strncpy(classname, linkfile, maxlen);
    1.41 +		}
    1.42 +		return classname;
    1.43 +	}
    1.44 +#endif /* linux */
    1.45 +
    1.46 +	/* Finally use the default we've used forever */
    1.47 +	strncpy(classname, "SDL_App", maxlen);
    1.48 +	return classname;
    1.49 +}
    1.50 +
    1.51  /* Create auxiliary (toplevel) windows with the current visual */
    1.52  static void create_aux_windows(_THIS)
    1.53  {
    1.54 -    char * savedclassname = NULL;
    1.55 +    char classname[1024];
    1.56      XSetWindowAttributes xattr;
    1.57      XWMHints *hints;
    1.58      XTextProperty titleprop, iconprop;
    1.59 @@ -368,15 +412,11 @@
    1.60  		 | PropertyChangeMask | StructureNotifyMask | KeymapStateMask);
    1.61  
    1.62      /* Set the class hints so we can get an icon (AfterStep) */
    1.63 +    get_classname(classname, sizeof(classname));
    1.64      {
    1.65  	XClassHint *classhints;
    1.66  	classhints = pXAllocClassHint();
    1.67  	if(classhints != NULL) {
    1.68 -            char *classname = getenv("SDL_VIDEO_X11_WMCLASS");
    1.69 -            if ( ! classname ) {
    1.70 -                classname = "SDL_App";
    1.71 -            }
    1.72 -	    savedclassname = strdup(classname);
    1.73  	    classhints->res_name = classname;
    1.74  	    classhints->res_class = classname;
    1.75  	    pXSetClassHint(SDL_Display, WMwindow, classhints);
    1.76 @@ -389,7 +429,7 @@
    1.77      SDL_IC = NULL;
    1.78  
    1.79      #ifdef X_HAVE_UTF8_STRING
    1.80 -    SDL_IM = pXOpenIM(SDL_Display, NULL, savedclassname, savedclassname);
    1.81 +    SDL_IM = pXOpenIM(SDL_Display, NULL, classname, classname);
    1.82      if (SDL_IM == NULL) {
    1.83  	SDL_SetError("no input method could be opened");
    1.84      } else {
    1.85 @@ -397,8 +437,8 @@
    1.86  			XNClientWindow, WMwindow,
    1.87  			XNFocusWindow, WMwindow,
    1.88  			XNInputStyle, XIMPreeditNothing  | XIMStatusNothing,
    1.89 -			XNResourceName, savedclassname,
    1.90 -			XNResourceClass, savedclassname,
    1.91 +			XNResourceName, classname,
    1.92 +			XNResourceClass, classname,
    1.93  			NULL);
    1.94  	if (SDL_IC == NULL) {
    1.95  		SDL_SetError("no input context could be created");
    1.96 @@ -408,9 +448,6 @@
    1.97      }
    1.98      #endif
    1.99  
   1.100 -    free(savedclassname);
   1.101 -
   1.102 -
   1.103      /* Allow the window to be deleted by the window manager */
   1.104      WM_DELETE_WINDOW = pXInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
   1.105      pXSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);