Unicode-only locales, such as Hindi (India), can only be used as a system locale if activating Windows 10's beta support for the UTF-8 code page. In such cases the Powershell's Set-WinSystemLocale API automatically and unconditionally sets the ACP&co code pages to UTF-8. In contrast intl.cpl has no support for UTF-8 (or for explicitly modifying the code pages) and refuses to use a Unicode-only system locale. So to keep a consistent SetWinLocale behavior, reset the system locale to en-US if it requires UTF-8 support and the --utf8 option was not specified.
Also note that UTF-8 is only supported on Windows 10+ and that forcing UTF-8 through the registry makes Windows unbootable.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- Interestingly even English locales can be Unicode-only: see en-AE. --- testbot/bin/SetWinLocale | 11 ++++++++++- testbot/bin/SetWinLocale.ps1 | 30 ++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/testbot/bin/SetWinLocale b/testbot/bin/SetWinLocale index 9f89280ab9..78c838465f 100755 --- a/testbot/bin/SetWinLocale +++ b/testbot/bin/SetWinLocale @@ -524,6 +524,9 @@ if (defined $Usage) print " --system SYS Specifies the system locale (see --defaults).\n"; print " . This requires elevated privileges.\n"; print " . Only takes effect after a reboot.\n"; + print " . Windows only allows using a Unicode-only locale (such as\n"; + print " hi-IN) as the system locale when setting the code pages to\n"; + print " UTF-8.\n"; print " . Windows 10 GUI: Time & language -> Language ->\n"; print " Administrative Language Settings -> Change system locale.\n"; print " . APIs: GetSystemDefaultLCID(), GetThreadLocale().\n"; @@ -841,7 +844,7 @@ sub SetWinLocales($$$$$$$$)
my $Cmd = ["powershell.exe", "-ExecutionPolicy", "ByPass", "-File", "$name0.ps1", "locales", $Locale || ".", $CountryId || ".", - $System || ".", $UTF8 ? "true" : "false", $MUI || ".", + $System || ".", $UTF8 ? "force" : "no", $MUI || ".", $KeyboardIds ? $KeyboardIds->[0] : ".", $SysCopy ? "true" : "false", $DefCopy ? "true" : "false", $OptUseIntl ? "true" : "false"]; @@ -853,6 +856,12 @@ sub SetWinLocales($$$$$$$$) { $Line =~ s/\r$//; Info("$Line\n"); + if ($Line eq "Setting the system locale to en-US instead") + { + # For the final checks + $OptSystem = "en-US"; + $LCIDSystem = "0409"; + } } }
diff --git a/testbot/bin/SetWinLocale.ps1 b/testbot/bin/SetWinLocale.ps1 index 00e9a1af14..a79d3c92fd 100644 --- a/testbot/bin/SetWinLocale.ps1 +++ b/testbot/bin/SetWinLocale.ps1 @@ -190,7 +190,7 @@ function SetCodePages($Value)
$SWC_Success = $True
-function SetWinCulture([string]$Locale, [string]$CountryId, [string]$System, [bool]$UTF8, [string]$MUI, [string]$KeyboardId, [bool]$SysCopy, [bool]$DefCopy) +function SetWinCulture([string]$Locale, [string]$CountryId, [string]$System, [string]$UTF8, [string]$MUI, [string]$KeyboardId, [bool]$SysCopy, [bool]$DefCopy) { $Cmd = Get-Command Set-Culture -ErrorAction SilentlyContinue if ($Cmd -eq $null) { @@ -201,8 +201,22 @@ function SetWinCulture([string]$Locale, [string]$CountryId, [string]$System, [bo
if ($Locale) { Set-Culture $Locale } if ($CountryId) { Set-WinHomeLocation $CountryId } - if ($System) { Set-WinSystemLocale $System } - if ($UTF8) { SetCodePages(65001) } + if ($System) + { + Set-WinSystemLocale $System + $ACP = Get-ItemProperty -Path $HKLM_CODE_PAGE -Name "ACP" -ErrorAction SilentlyContinue + if ($ACP.ACP -eq "65001") + { + Write-Output "$System is a UTF-8 system locale" + if ($UTF8 -eq "no") + { + Write-Output "Setting the system locale to en-US instead" + Set-WinSystemLocale "en-US" + } + $UTF8 = "" + } + } + if ($UTF8 -eq "force") { SetCodePages(65001) } if ($MUI) { Set-WinUILanguageOverride $MUI } if ($KeyboardId) { Set-WinDefaultInputMethodOverride $KeyboardId } if ($SysCopy -or $DefCopy) @@ -253,7 +267,7 @@ function SetLocales($Argv) $Locale = GetStringArg($Argv[1]) $CountryId = GetStringArg($Argv[2]) $System = GetStringArg($Argv[3]) - $UTF8 = $Argv[4] -eq "true" + $UTF8 = GetStringArg($Argv[4]) $MUI = GetStringArg($Argv[5]) $KeyboardId = GetStringArg($Argv[6]) $SysCopy = $Argv[7] -ne "false" @@ -272,7 +286,7 @@ function SetLocales($Argv) RunIntlCpl "$Name0.xml" Remove-Item -Path "$Name0.xml"
- if ($UTF8) { SetCodePages(65001) } + if ($UTF8 -eq "force") { SetCodePages(65001) } exit 0 }
@@ -298,7 +312,11 @@ function ShowUsage() Write-Output " LOCALE Is the BCP-47 locale to use for formats, date and time." Write-Output " COUNTRYID Is the numerical country code." Write-Output " SYSTEM Is the BCP-47 locale to use as the system locale." - Write-Output " UTF8 If set to 'true' the code pages will be changed to UTF-8." + Write-Output " UTF8 If set to 'force' the code pages will be changed to UTF-8" + Write-Output " regardless of the system locale." + Write-Output " If set to 'allow' the code pages will be set to match the system" + Write-Output " locale even if that implies using UTF-8. This is the default." + Write-Output " If set to 'no' Unicode-only locales will be replaced with en-US." Write-Output " MUI Is the BCP-47 locale to use for the display language." Write-Output " KEYBOARDID Is the keyboard identifier to set as the default." Write-Output " SYSCOPY If 'true' the locale settings will be copied to the system accounts"
For instance intl.cpl fails to set it to en-CA while the Powershell APIs automatically convert it to en-GB. Take this into account before checking that the locale modifications succeeded.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- This is also why the TestBot's Windows VMs used ar-EG instead of ar-MA like the Debian VMs. Now either would work. --- testbot/bin/SetWinLocale | 7 +++++++ testbot/bin/SetWinLocale.ps1 | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/SetWinLocale b/testbot/bin/SetWinLocale index 78c838465f..0d4c305ceb 100755 --- a/testbot/bin/SetWinLocale +++ b/testbot/bin/SetWinLocale @@ -543,6 +543,9 @@ if (defined $Usage) print " Set-WinSystemLocale for the relevant locales.\n"; print " --mui MUI Specifies the display language (see --defaults).\n"; print " . Only takes effect after a log out + log in.\n"; + print " . Windows sometimes uses a different locale string. For\n"; + print " instance setting the display language to English (Canada) sets\n"; + print " this to en-GB instead of en-CA.\n"; print " . Windows 10 GUI: Time & language -> Language -> Windows\n"; print " display language.\n"; print " . APIs: GetSystemPreferredUILanguages() (--sys-copy case),\n"; @@ -862,6 +865,10 @@ sub SetWinLocales($$$$$$$$) $OptSystem = "en-US"; $LCIDSystem = "0409"; } + elsif ($Line =~ /^Windows uses (.*) for the MUI language/) + { + $OptMUI = $1; # for the final check + } } }
diff --git a/testbot/bin/SetWinLocale.ps1 b/testbot/bin/SetWinLocale.ps1 index a79d3c92fd..e6025216bf 100644 --- a/testbot/bin/SetWinLocale.ps1 +++ b/testbot/bin/SetWinLocale.ps1 @@ -189,6 +189,7 @@ function SetCodePages($Value) }
$SWC_Success = $True +$SWC_MUI = $null
function SetWinCulture([string]$Locale, [string]$CountryId, [string]$System, [string]$UTF8, [string]$MUI, [string]$KeyboardId, [bool]$SysCopy, [bool]$DefCopy) { @@ -217,7 +218,16 @@ function SetWinCulture([string]$Locale, [string]$CountryId, [string]$System, [st } } if ($UTF8 -eq "force") { SetCodePages(65001) } - if ($MUI) { Set-WinUILanguageOverride $MUI } + if ($MUI) + { + Set-WinUILanguageOverride $MUI + $WinMUI = Get-ItemProperty -Path $HKCU_DESKTOP -Name "PreferredUILanguagesPending" -ErrorAction SilentlyContinue + $global:SWC_MUI = $WinMUI.PreferredUILanguagesPending + if ($SWC_MUI -ne $MUI) + { + Write-Output "Windows uses $SWC_MUI for the MUI language instead of $MUI" + } + } if ($KeyboardId) { Set-WinDefaultInputMethodOverride $KeyboardId } if ($SysCopy -or $DefCopy) { @@ -282,7 +292,8 @@ function SetLocales($Argv) Write-Output "Falling back to intl.cpl" }
- WriteIntlCplConfig $Locale $CountryId $System $MUI $KeyboardId $SysCopy $DefCopy >"$Name0.xml" + if ($SWC_MUI -eq $null) { $global:SWC_MUI = $MUI } + WriteIntlCplConfig $Locale $CountryId $System $SWC_MUI $KeyboardId $SysCopy $DefCopy >"$Name0.xml" RunIntlCpl "$Name0.xml" Remove-Item -Path "$Name0.xml"