diff --git a/src/kits/locale/Jamfile b/src/kits/locale/Jamfile index 897b16d6d3..42a087add6 100644 --- a/src/kits/locale/Jamfile +++ b/src/kits/locale/Jamfile @@ -52,7 +52,7 @@ Includes [ FGristFiles $(sources) ] : $(HAIKU_ICU_HEADERS_DEPENDENCY) ; # Dependency needed to trigger downloading/unzipping the package before # compiling the files. -AddResources liblocale.so : CountryFlags.rdef ; +AddResources liblocale.so : CountryFlags.rdef LanguageFlags.rdef ; SharedLibrary liblocale.so : $(sources) @@ -72,7 +72,7 @@ SEARCH on [ FGristFiles Dragger.cpp ] += [ FDirName $(HAIKU_TOP) src kits interf SEARCH on [ FGristFiles Menu.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; SEARCH on [ FGristFiles PrintJob.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; SEARCH on [ FGristFiles ZombieReplicantView.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; - + DoCatalogs liblocale.so : system : diff --git a/src/kits/locale/LanguageFlags.rdef b/src/kits/locale/LanguageFlags.rdef index 6ea52f353a..4579778079 100644 --- a/src/kits/locale/LanguageFlags.rdef +++ b/src/kits/locale/LanguageFlags.rdef @@ -1,5 +1,5 @@ // Flag data for Esperanto -resource(0,"EO") #'VICN' array { +resource(5000, "eo") #'VICN' array { $"6E6369660305FF057E03009900020A0AC46BC0C0C35DC3FF50C1FEC8E2C3FFC7" $"D4C0C0CA97BEBFC72DBEBF50BB7FC512BEBFC1A8BEBF0A0421295F295F572157" $"040A02010102401084000000000000401642C01084C0C8590A000101023D18C6" diff --git a/src/kits/locale/LocaleRoster.cpp b/src/kits/locale/LocaleRoster.cpp index fd77f1cfd7..7eaf22db79 100644 --- a/src/kits/locale/LocaleRoster.cpp +++ b/src/kits/locale/LocaleRoster.cpp @@ -66,6 +66,26 @@ int32 BLocaleRoster::kEmbeddedCatResId = 0xCADA; // this may live in an app- or add-on-file +static status_t +load_resources_if_needed(RosterData* rosterData) +{ + if (rosterData->fAreResourcesLoaded) + return B_OK; + + status_t result = rosterData->fResources.SetToImage( + (const void*)&BLocaleRoster::Default); + if (result != B_OK) + return result; + + result = rosterData->fResources.PreloadResourceType(); + if (result != B_OK) + return result; + + rosterData->fAreResourcesLoaded = true; + return B_OK; +} + + static const char* country_code_for_language(const BLanguage& language) { @@ -302,31 +322,23 @@ BLocaleRoster::GetFlagIconForCountry(BBitmap* flagIcon, const char* countryCode) if (!lock.IsLocked()) return B_ERROR; - if (!rosterData->fAreResourcesLoaded) { - status_t result = rosterData->fResources.SetToImage( - (const void*)&BLocaleRoster::Default); - if (result != B_OK) - return result; + status_t status = load_resources_if_needed(rosterData); + if (status != B_OK) + return status; - result = rosterData->fResources.PreloadResourceType(); - if (result != B_OK) - return result; - - rosterData->fAreResourcesLoaded = true; - } - - size_t size; - - // normalize the country code : 2 letters uparcase - // filter things out so that "pt_BR" gived the flag for brazil - char normalizedCode[3]; - normalizedCode[2] = '\0'; + // Normalize the country code: 2 letters uppercase + // filter things out so that "pt_BR" gives the flag for brazil int codeLength = strlen(countryCode); + if (codeLength < 2) + return B_BAD_VALUE; + char normalizedCode[3]; normalizedCode[0] = toupper(countryCode[codeLength - 2]); normalizedCode[1] = toupper(countryCode[codeLength - 1]); + normalizedCode[2] = '\0'; + size_t size; const void* buffer = rosterData->fResources.LoadResource( B_VECTOR_ICON_TYPE, normalizedCode, &size); if (buffer == NULL || size == 0) @@ -345,7 +357,32 @@ BLocaleRoster::GetFlagIconForLanguage(BBitmap* flagIcon, || languageCode[1] == '\0') return B_BAD_VALUE; - // TODO: Languages like Esperanto have a flag, but no country + RosterData* rosterData = RosterData::Default(); + BAutolock lock(rosterData->fLock); + if (!lock.IsLocked()) + return B_ERROR; + + status_t status = load_resources_if_needed(rosterData); + if (status != B_OK) + return status; + + // Normalize the language code: first two letters, lowercase + + char normalizedCode[3]; + normalizedCode[0] = tolower(languageCode[0]); + normalizedCode[1] = tolower(languageCode[1]); + normalizedCode[2] = '\0'; + + size_t size; + const void* buffer = rosterData->fResources.LoadResource( + B_VECTOR_ICON_TYPE, normalizedCode, &size); + if (buffer != NULL && size != 0) { + return BIconUtils::GetVectorIcon(static_cast(buffer), + size, flagIcon); + } + + // There is no language flag, try to get the default country's flag for + // the language instead. BLanguage language(languageCode); const char* countryCode = country_code_for_language(language);