Skip to content

Commit

Permalink
Merge branch 'master' of ssh://github.com/gnustep/libs-base
Browse files Browse the repository at this point in the history
  • Loading branch information
rfm committed Aug 7, 2024
2 parents 72c975c + 81b3c72 commit 023e8a6
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Headers/GNUstepBase/GSConfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ typedef struct {

# if defined(__MINGW__)
# include <w32api.h>
# define GS_WINVER Windows2000
# define GS_WINVER WindowsVista
# elif defined(_MSC_VER)
# include <WinSDKVer.h>
# define GS_WINVER _WIN32_WINNT_WIN10
Expand Down
50 changes: 48 additions & 2 deletions Source/NSProcessInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -1605,28 +1605,74 @@ - (void) performExpiringActivityWithReason: (NSString *)reason
}
}

// get current time zone
char *localeList = NULL;
#if __ANDROID_API__ >= 24
// get locales ordered by user preference
jclass localeListCls = (*env)->FindClass(env, "android/os/LocaleList");
jmethodID localeListGetDefaultMethod = (*env)->GetStaticMethodID(env, localeListCls, "getDefault", "()Landroid/os/LocaleList;");
jobject localeListObj = (*env)->CallStaticObjectMethod(env, localeListCls, localeListGetDefaultMethod);

if (localeCls) {
// Retrieve string representation of the locale list
jmethodID localeListToLanguageTagsMethod = (*env)->GetMethodID(env, localeListCls, "toLanguageTags", "()Ljava/lang/String;");
jstring localeListJava = (*env)->CallObjectMethod(env, localeListObj, localeListToLanguageTagsMethod);

if (localeListJava) {
const char *localeListOrig = (*env)->GetStringUTFChars(env, localeIdJava, NULL);

// Some devices return with it enclosed in []'s so check if both exists before
// removing to ensure it is formatted correctly
if (localeListOrig[0] == '[' && localeListOrig[strlen(localeListOrig) - 1] == ']') {
localeList = strdup(localeListOrig + 1);
localeList[strlen(localeList) - 1] = '\0';
} else {
localeList = strdup(localeListOrig);
}

// NOTE: This is an IETF BCP 47 language tag and may not correspond exactly tocorrespond ll-CC format
// e.g. gsw-u-sd-chzh is a valid BCP 47 language tag, but uses an ISO 639-3 subtag to classify the language.
// There is no easy fix to this, as we use ISO 639-2 subtags internally.
for (int i = 0; localeList[i]; i++) {
if (localeList[i] == '-') {
localeList[i] = '_';
}
}

(*env)->ReleaseStringUTFChars(env, localeListJava, localeListOrig);
}
}
#endif


jclass timezoneCls = (*env)->FindClass(env, "java/util/TimeZone");
jmethodID timezoneDefaultMethod = (*env)->GetStaticMethodID(env, timezoneCls, "getDefault", "()Ljava/util/TimeZone;");
jmethodID timezoneIdMethod = (*env)->GetMethodID(env, timezoneCls, "getID", "()Ljava/lang/String;");
jobject timezoneObj = (*env)->CallStaticObjectMethod(env, timezoneCls, timezoneDefaultMethod);
jstring timezoneIdJava = (*env)->CallObjectMethod(env, timezoneObj, timezoneIdMethod);
const char *timezoneId = (*env)->GetStringUTFChars(env, timezoneIdJava, NULL);

char *localeListValue = "";
if (localeList) {
localeListValue = localeList;
}

// initialize process with these options
char *argv[] = {
arg0,
"-Locale", localeId,
"-Local Time Zone", (char *)timezoneId,
"-GSAndroidLocaleList", localeListValue,
"-GSLogSyslog", "YES" // use syslog (available via logcat) instead of stdout/stderr (not available on Android)
};

GSInitializeProcessAndroidWithArgs(env, context, sizeof(argv)/sizeof(char *), argv, NULL);

free(arg0);
free(localeId);
free(localeList);
(*env)->ReleaseStringUTFChars(env, packageCodePathJava, packageCodePath);
(*env)->ReleaseStringUTFChars(env, packageNameJava, packageName);
(*env)->ReleaseStringUTFChars(env, localeIdJava, localeId);
(*env)->ReleaseStringUTFChars(env, localeIdJava, localeIdOrig);
(*env)->ReleaseStringUTFChars(env, timezoneIdJava, timezoneId);
}

Expand Down
95 changes: 94 additions & 1 deletion Source/NSUserDefaults.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
#import "GNUstepBase/NSString+GNUstepBase.h"

#if defined(_WIN32)
#import "win32/NSString+Win32Additions.h"

#include <winnls.h>

/* Fake interface to avoid compiler warnings
*/
@interface NSUserDefaultsWin32 : NSUserDefaults
Expand Down Expand Up @@ -355,6 +359,94 @@ - (BOOL) synchronize;
{
NSMutableArray *names = [NSMutableArray arrayWithCapacity: 10];

#ifdef WIN32
NSEnumerator *enumerator;
NSArray *languages;
NSString *locale;
BOOL ret;

unsigned long numberOfLanguages = 0;
unsigned long length = 7;
unsigned long factor = sizeof(wchar_t);
wchar_t *buffer = malloc(length * factor);
if (!buffer)
{
return names;
}

/* Returns a wchar_t list of languages in the form ll-CC, where ll is the
* two-letter language code, and CC is the two-letter country code.
*/
ret = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numberOfLanguages,
buffer, &length);
if (!ret)
{
length = 0;
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numberOfLanguages,
NULL, &length)) {
wchar_t *oldBuffer = buffer;
buffer = realloc(buffer, length * factor);
if (!buffer)
{
free(oldBuffer);
return names;
}

ret = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numberOfLanguages, buffer, &length);
if (!ret)
{
free(buffer);
return names;
}
}
}

languages = [NSString arrayFromWCharList:buffer length:length];
enumerator = [languages objectEnumerator];
free(buffer);

while (nil != (locale = [enumerator nextObject]))
{
/* Replace "-" Separator with "_" */
locale = [locale stringByReplacingOccurrencesOfString:@"-" withString:@"_"];
[names addObjectsFromArray: GSLanguagesFromLocale(locale)];
}
#elif defined(__ANDROID__)
// When running on Android, the process must be correctly initialized
// with GSInitializeProcessAndroid (See NSProcessInfo).
//
// If the minimum API level is 24 or higher, the user-prefered locales
// are retrieved from the Android system and passed as GSAndroidLocaleList
// process argument
NSArray *args = [[NSProcessInfo processInfo] arguments];
NSEnumerator *enumerator = [args objectEnumerator];
NSString *key = nil;
NSString *localeList = nil;

[enumerator nextObject]; // Skip process name.
while (nil != (key = [enumerator nextObject]))
{
if ([key isEqualToString:@"-GSAndroidLocaleList"])
{
localeList = [enumerator nextObject];
break;
}
}

// The locale list is a comma-separated list of locales of form ll-CC
if (localeList != nil)
{
NSString *locale;
NSArray *locales = [localeList componentsSeparatedByString: @","];

enumerator = [locales objectEnumerator];
while (nil != (locale = [enumerator nextObject]))
{
[names addObjectsFromArray: GSLanguagesFromLocale(locale)];
}
}
#else
// Add the languages listed in the LANGUAGE environment variable
// (a non-POSIX GNU extension)
{
Expand All @@ -371,7 +463,7 @@ - (BOOL) synchronize;
}
}
}

// If LANGUAGES did not yield any languages, try LC_MESSAGES

if ([names count] == 0)
Expand All @@ -383,6 +475,7 @@ - (BOOL) synchronize;
[names addObjectsFromArray: GSLanguagesFromLocale(locale)];
}
}
#endif

return names;
}
Expand Down
1 change: 1 addition & 0 deletions Source/win32/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ win32_OBJC_FILES =\
NSMessagePortNameServer.m \
NSStream.m \
NSUserDefaults.m \
NSString+Win32Additions.m\

-include Makefile.preamble

Expand Down
40 changes: 40 additions & 0 deletions Source/win32/NSString+Win32Additions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/** Category for converting Windows Strings
Copyright (C) 1998 Free Software Foundation, Inc.
Written by: Hugo Melder <[email protected]>
Created: July 2024
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110 USA.
*/

#import <Foundation/NSString.h>

#include <wchar.h>

/**
* Converts a wchar_t list to an array of strings.
* The list is NULL-delimited and terminated by two NULL (wchar_t) characters.
*
* The encoding is Unicode (UTF-16LE).
*/
@interface NSString (Win32Additions)

+ (GS_GENERIC_CLASS(NSArray, NSString *) *) arrayFromWCharList: (wchar_t *)list
length: (unsigned long)length;

@end
45 changes: 45 additions & 0 deletions Source/win32/NSString+Win32Additions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/** Category for converting Windows Strings
Copyright (C) 1998 Free Software Foundation, Inc.
Written by: Hugo Melder <[email protected]>
Created: July 2024
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110 USA.
*/

#import "NSString+Win32Additions.h"

@implementation NSString (Win32Additions)

+ (GS_GENERIC_CLASS(NSArray, NSString *) *) arrayFromWCharList: (wchar_t *)list
length: (unsigned long)length
{
NSString *string;
GS_GENERIC_CLASS(NSArray, NSString *) * array;

string = [[NSString alloc] initWithBytes: list
length: (length - 2) * sizeof(wchar_t)
encoding: NSUTF16LittleEndianStringEncoding];

array = [string componentsSeparatedByString: @"\0"];
RELEASE(string);

return array;
}

@end

0 comments on commit 023e8a6

Please sign in to comment.