Beispiel #1
0
const char *
_nl_language_preferences_default (void)
{
#if HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
  {
    /* Cache the preferences list, since CoreFoundation calls are expensive.  */
    static const char *cached_languages;
    static int cache_initialized;

    if (!cache_initialized)
      {
	CFTypeRef preferences =
	  CFPreferencesCopyAppValue (CFSTR ("AppleLanguages"),
				     kCFPreferencesCurrentApplication);
	if (preferences != NULL
	    && CFGetTypeID (preferences) == CFArrayGetTypeID ())
	  {
	    CFArrayRef prefArray = (CFArrayRef)preferences;
	    int n = CFArrayGetCount (prefArray);
	    char buf[256];
	    size_t size = 0;
	    int i;

	    for (i = 0; i < n; i++)
	      {
		CFTypeRef element = CFArrayGetValueAtIndex (prefArray, i);
		if (element != NULL
		    && CFGetTypeID (element) == CFStringGetTypeID ()
		    && CFStringGetCString ((CFStringRef)element,
					   buf, sizeof (buf),
					   kCFStringEncodingASCII))
		  {
		    _nl_locale_name_canonicalize (buf);
		    size += strlen (buf) + 1;
		    /* Most GNU programs use msgids in English and don't ship
		       an en.mo message catalog.  Therefore when we see "en"
		       in the preferences list, arrange for gettext() to
		       return the msgid, and ignore all further elements of
		       the preferences list.  */
		    if (strcmp (buf, "en") == 0)
		      break;
		  }
		else
		  break;
	      }
	    if (size > 0)
	      {
		char *languages = (char *) malloc (size);

		if (languages != NULL)
		  {
		    char *p = languages;

		    for (i = 0; i < n; i++)
		      {
			CFTypeRef element =
			  CFArrayGetValueAtIndex (prefArray, i);
			if (element != NULL
		            && CFGetTypeID (element) == CFStringGetTypeID ()
			    && CFStringGetCString ((CFStringRef)element,
						   buf, sizeof (buf),
						   kCFStringEncodingASCII))
			  {
			    _nl_locale_name_canonicalize (buf);
			    strcpy (p, buf);
			    p += strlen (buf);
			    *p++ = ':';
			    if (strcmp (buf, "en") == 0)
			      break;
			  }
			else
			  break;
		      }
		    *--p = '\0';

		    cached_languages = languages;
		  }
	      }
	  }
	cache_initialized = 1;
      }
    if (cached_languages != NULL)
      return cached_languages;
  }
#endif

#ifdef WIN32_NATIVE
  {
    /* Cache the preferences list, since computing it is expensive.  */
    static const char *cached_languages;
    static int cache_initialized;

    /* Activate the new code only when the GETTEXT_MUI environment variable is
       set, for the time being, since the new code is not well tested.  */
    if (!cache_initialized && getenv ("GETTEXT_MUI") != NULL)
      {
	const char *languages = NULL;
	HMODULE kernel32 = GetModuleHandle ("kernel32");

	if (kernel32 != NULL)
	  languages = _nl_language_preferences_win32_mui (kernel32);

	if (languages == NULL && kernel32 != NULL)
	  languages = _nl_language_preferences_win32_ME (kernel32);

	if (languages == NULL)
	  languages = _nl_language_preferences_win32_95 ();

	if (languages == NULL && kernel32 != NULL)
	  languages = _nl_language_preferences_win32_system (kernel32);

	cached_languages = languages;
	cache_initialized = 1;
      }
    if (cached_languages != NULL)
      return cached_languages;
  }
#endif

  return NULL;
}
Beispiel #2
0
/* Get the preferences list through the MUI APIs. This works on Windows Vista
   and newer.  */
static const char *
_nl_language_preferences_win32_mui (HMODULE kernel32)
{
  /* DWORD GetUserPreferredUILanguages (ULONG dwFlags,
					PULONG pulNumLanguages,
					PWSTR pwszLanguagesBuffer,
					PULONG pcchLanguagesBuffer);  */
  typedef DWORD (WINAPI *GetUserPreferredUILanguages_func) (ULONG, PULONG, PWSTR, PULONG);
  GetUserPreferredUILanguages_func p_GetUserPreferredUILanguages;

  p_GetUserPreferredUILanguages =
   (GetUserPreferredUILanguages_func)
   GetProcAddress (kernel32, "GetUserPreferredUILanguages");
  if (p_GetUserPreferredUILanguages != NULL)
    {
      ULONG num_languages;
      ULONG bufsize;
      DWORD ret;

      bufsize = 0;
      ret = p_GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,
					   &num_languages,
					   NULL, &bufsize);
      if (ret == 0
	  && GetLastError () == STATUS_BUFFER_OVERFLOW
	  && bufsize > 0)
	{
	  WCHAR *buffer = (WCHAR *) malloc (bufsize * sizeof (WCHAR));
	  if (buffer != NULL)
	    {
	      ret = p_GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,
						   &num_languages,
						   buffer, &bufsize);
	      if (ret)
		{
		  /* Convert the list from NUL-delimited WCHAR[] Win32 locale
		     names to colon-delimited char[] Unix locale names.
		     We assume that all these locale names are in ASCII,
		     nonempty and contain no colons.  */
		  char *languages =
		    (char *) malloc (bufsize + num_languages * 10 + 1);
		  if (languages != NULL)
		    {
		      const WCHAR *p = buffer;
		      char *q = languages;
		      ULONG i;
		      for (i = 0; i < num_languages; i++)
			{
			  char *q1;
			  char *q2;

			  q1 = q;
			  if (i > 0)
			    *q++ = ':';
			  q2 = q;
			  for (; *p != (WCHAR)'\0'; p++)
			    {
			      if ((unsigned char) *p != *p || *p == ':')
				{
				  /* A non-ASCII character or a colon inside
				     the Win32 locale name! Punt.  */
				  q = q1;
				  break;
				}
			      *q++ = (unsigned char) *p;
			    }
			  if (q == q1)
			    /* An unexpected Win32 locale name occurred.  */
			    break;
			  *q = '\0';
			  _nl_locale_name_canonicalize (q2);
			  q = q2 + strlen (q2);
			  p++;
			}
		      *q = '\0';
		      if (q > languages)
			{
			  free (buffer);
			  return languages;
			}
		      free (languages);
		    }
		}
	      free (buffer);
	    }
	}
    }
  return NULL;
}
const char *
_nl_language_preferences_default (void)
{
#if HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
  {
    /* Cache the preferences list, since CoreFoundation calls are expensive.  */
    static const char *cached_languages;
    static int cache_initialized;

    if (!cache_initialized)
      {
	CFTypeRef preferences =
	  CFPreferencesCopyAppValue (CFSTR ("AppleLanguages"),
				     kCFPreferencesCurrentApplication);
	if (preferences != NULL
	    && CFGetTypeID (preferences) == CFArrayGetTypeID ())
	  {
	    CFArrayRef prefArray = (CFArrayRef)preferences;
	    int n = CFArrayGetCount (prefArray);
	    char buf[256];
	    size_t size = 0;
	    int i;

	    for (i = 0; i < n; i++)
	      {
		CFTypeRef element = CFArrayGetValueAtIndex (prefArray, i);
		if (element != NULL
		    && CFGetTypeID (element) == CFStringGetTypeID ()
		    && CFStringGetCString ((CFStringRef)element,
					   buf, sizeof (buf),
					   kCFStringEncodingASCII))
		  {
		    _nl_locale_name_canonicalize (buf);
		    size += strlen (buf) + 1;
		    /* Most GNU programs use msgids in English and don't ship
		       an en.mo message catalog.  Therefore when we see "en"
		       in the preferences list, arrange for gettext() to
		       return the msgid, and ignore all further elements of
		       the preferences list.  */
		    if (strcmp (buf, "en") == 0)
		      break;
		  }
		else
		  break;
	      }
	    if (size > 0)
	      {
		char *languages = (char *) malloc (size);

		if (languages != NULL)
		  {
		    char *p = languages;

		    for (i = 0; i < n; i++)
		      {
			CFTypeRef element =
			  CFArrayGetValueAtIndex (prefArray, i);
			if (element != NULL
		            && CFGetTypeID (element) == CFStringGetTypeID ()
			    && CFStringGetCString ((CFStringRef)element,
						   buf, sizeof (buf),
						   kCFStringEncodingASCII))
			  {
			    _nl_locale_name_canonicalize (buf);
			    strcpy (p, buf);
			    p += strlen (buf);
			    *p++ = ':';
			    if (strcmp (buf, "en") == 0)
			      break;
			  }
			else
			  break;
		      }
		    *--p = '\0';

		    cached_languages = languages;
		  }
	      }
	  }
	cache_initialized = 1;
      }
    if (cached_languages != NULL)
      return cached_languages;
  }
#endif

  return NULL;
}