1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 use winapi::IDWriteLocalizedStrings;
6 use winapi::wchar_t;
7 use comptr::ComPtr;
8 use winapi::winerror::S_OK;
9 use winapi::minwindef::{BOOL, FALSE};
10 use kernel32;
11 use std::ffi::{OsStr};
12 use std::os::windows::ffi::{OsStrExt};
13
14 lazy_static! {
15 static ref SYSTEM_LOCALE: Vec<wchar_t> = {
16 unsafe {
17 let mut locale: Vec<wchar_t> = vec![0; 85];
18 kernel32::GetUserDefaultLocaleName(locale.as_mut_ptr(), locale.len() as i32 - 1);
19 locale
20 }
21 };
22 static ref EN_US_LOCALE: Vec<wchar_t> = {
23 OsStr::new("en-us").encode_wide().collect()
24 };
25 }
26
get_locale_string(strings: &mut ComPtr<IDWriteLocalizedStrings>) -> String27 pub fn get_locale_string(strings: &mut ComPtr<IDWriteLocalizedStrings>) -> String {
28 unsafe {
29 let mut index: u32 = 0;
30 let mut exists: BOOL = FALSE;
31 let hr = strings.FindLocaleName((*SYSTEM_LOCALE).as_ptr(), &mut index, &mut exists);
32 if hr != S_OK || exists == FALSE {
33 let hr = strings.FindLocaleName((*EN_US_LOCALE).as_ptr(), &mut index, &mut exists);
34 if hr != S_OK || exists == FALSE {
35 // Ultimately fall back to first locale on list
36 index = 0;
37 }
38 }
39
40 let mut length: u32 = 0;
41 let hr = strings.GetStringLength(index, &mut length);
42 assert!(hr == 0);
43
44 let mut name: Vec<wchar_t> = Vec::with_capacity(length as usize + 1);
45 let hr = strings.GetString(index, name.as_mut_ptr(), length + 1);
46 assert!(hr == 0);
47 name.set_len(length as usize);
48
49 String::from_utf16(&name).ok().unwrap()
50 }
51 }
52
53 // ToWide from https://github.com/retep998/wio-rs/blob/master/src/wide.rs
54
55 pub trait ToWide {
to_wide(&self) -> Vec<u16>56 fn to_wide(&self) -> Vec<u16>;
to_wide_null(&self) -> Vec<u16>57 fn to_wide_null(&self) -> Vec<u16>;
58 }
59
60 impl<T> ToWide for T where T: AsRef<OsStr> {
to_wide(&self) -> Vec<u16>61 fn to_wide(&self) -> Vec<u16> {
62 self.as_ref().encode_wide().collect()
63 }
to_wide_null(&self) -> Vec<u16>64 fn to_wide_null(&self) -> Vec<u16> {
65 self.as_ref().encode_wide().chain(Some(0)).collect()
66 }
67 }
68