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::um::dwrite::IDWriteLocalizedStrings;
6 use winapi::ctypes::wchar_t;
7 use comptr::ComPtr;
8 use winapi::shared::winerror::S_OK;
9 use winapi::shared::minwindef::{BOOL, FALSE};
10 use winapi::um::winnls::GetUserDefaultLocaleName;
11 use std::ffi::{OsStr};
12 use std::os::windows::ffi::{OsStrExt};
13 
14 
15 lazy_static! {
16     static ref SYSTEM_LOCALE: Vec<wchar_t> = {
17         unsafe {
18             let mut locale: Vec<wchar_t> = vec![0; 85];
19             GetUserDefaultLocaleName(locale.as_mut_ptr(), locale.len() as i32 - 1);
20             locale
21         }
22     };
23     static ref EN_US_LOCALE: Vec<wchar_t> = {
24         OsStr::new("en-us").encode_wide().collect()
25     };
26 }
27 
get_locale_string(strings: &mut ComPtr<IDWriteLocalizedStrings>) -> String28 pub fn get_locale_string(strings: &mut ComPtr<IDWriteLocalizedStrings>) -> String {
29     unsafe {
30         let mut index: u32 = 0;
31         let mut exists: BOOL = FALSE;
32         let hr = strings.FindLocaleName((*SYSTEM_LOCALE).as_ptr(), &mut index, &mut exists);
33         if hr != S_OK || exists == FALSE {
34             let hr = strings.FindLocaleName((*EN_US_LOCALE).as_ptr(), &mut index, &mut exists);
35             if hr != S_OK || exists == FALSE {
36                 // Ultimately fall back to first locale on list
37                 index = 0;
38             }
39         }
40 
41         let mut length: u32 = 0;
42         let hr = strings.GetStringLength(index, &mut length);
43         assert!(hr == 0);
44 
45         let mut name: Vec<wchar_t> = Vec::with_capacity(length as usize + 1);
46         let hr = strings.GetString(index, name.as_mut_ptr(), length + 1);
47         assert!(hr == 0);
48         name.set_len(length as usize);
49 
50         String::from_utf16(&name).ok().unwrap()
51     }
52 }
53 
54 // ToWide from https://github.com/retep998/wio-rs/blob/master/src/wide.rs
55 
56 pub trait ToWide {
to_wide(&self) -> Vec<u16>57     fn to_wide(&self) -> Vec<u16>;
to_wide_null(&self) -> Vec<u16>58     fn to_wide_null(&self) -> Vec<u16>;
59 }
60 
61 impl<T> ToWide for T where T: AsRef<OsStr> {
to_wide(&self) -> Vec<u16>62     fn to_wide(&self) -> Vec<u16> {
63         self.as_ref().encode_wide().collect()
64     }
to_wide_null(&self) -> Vec<u16>65     fn to_wide_null(&self) -> Vec<u16> {
66         self.as_ref().encode_wide().chain(Some(0)).collect()
67     }
68 }
69