/// <summary> /// Initializes a new instance of the /// <see cref="T:SIL.Windows.Forms.Keyboarding.Windows.WinKeyboardDescription"/> class. /// </summary> internal WinKeyboardDescription(string id, string name, string layout, string locale, bool isAvailable, IInputLanguage inputLanguage, WinKeyboardAdaptor engine, string localizedName, TfInputProcessorProfile profile) : base(id, name, layout, locale, isAvailable, engine) { InputLanguage = inputLanguage; _localizedName = localizedName; InputProcessorProfile = profile; ConversionMode = (int) (Win32.IME_CMODE.NATIVE | Win32.IME_CMODE.SYMBOL); _useNfcContext = !IsKeymanKeyboard(profile); }
/// <summary> /// Initializes a new instance of the /// <see cref="T:SIL.Windows.Forms.Keyboarding.Windows.WinKeyboardDescription"/> class. /// </summary> internal WinKeyboardDescription(string id, string name, string layout, string locale, bool isAvailable, IInputLanguage inputLanguage, WinKeyboardAdaptor engine, string localizedName, TfInputProcessorProfile profile) : base(id, name, layout, locale, isAvailable, engine) { InputLanguage = inputLanguage; _localizedName = localizedName; InputProcessorProfile = profile; ConversionMode = (int)(Win32.IME_CMODE.NATIVE | Win32.IME_CMODE.SYMBOL); _useNfcContext = !IsKeymanKeyboard(profile); }
private static bool InputProcessorProfilesEqual(TfInputProcessorProfile profile1, TfInputProcessorProfile profile2) { // Don't compare Flags - they can be different and it's still the same profile return(profile1.ProfileType == profile2.ProfileType && profile1.LangId == profile2.LangId && profile1.ClsId == profile2.ClsId && profile1.GuidProfile == profile2.GuidProfile && profile1.CatId == profile2.CatId && profile1.HklSubstitute == profile2.HklSubstitute && profile1.Caps == profile2.Caps && profile1.Hkl == profile2.Hkl); }
private static bool IsKeymanKeyboard(TfInputProcessorProfile profile) { if (profile.ProfileType != TfProfileType.InputProcessor) return false; // check the default key value for profile.ClsId. var subKey = string.Format(@"CLSID\{{{0}}}", profile.ClsId); using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(subKey)) { if (key == null) return false; var value = key.GetValue(null) as string; return value != null && value.Contains("Keyman"); } }
private static bool IsKeymanKeyboard(TfInputProcessorProfile profile) { if (profile.ProfileType != TfProfileType.InputProcessor) { return(false); } // check the default key value for profile.ClsId. var subKey = string.Format(@"CLSID\{{{0}}}", profile.ClsId); using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(subKey)) { if (key == null) { return(false); } var value = key.GetValue(null) as string; return(value != null && value.Contains("Keyman")); } }
private IEnumerable <LayoutName> GetAvailableKeyboardNames(InputLanguage inputLanguage) { IEnumTfInputProcessorProfiles profilesEnumerator; string cultureName; var culture = GetCultureInfoFromInputLanguage(inputLanguage, out cultureName); if (cultureName == UnknownLanguage) { Debug.WriteLine($"Error looking up keyboards with layout {inputLanguage.LayoutName} - invalid culture"); yield break; } try { profilesEnumerator = ProfileManager.EnumProfiles((short)culture.KeyboardLayoutId); } catch { Debug.WriteLine($"Error looking up keyboards for language {culture.Name} - {(short)culture.KeyboardLayoutId}"); yield break; } TfInputProcessorProfile[] profiles = new TfInputProcessorProfile[1]; bool returnedLanguage = false; while (profilesEnumerator.Next(1, profiles) == 1) { // We only deal with keyboards; skip other input methods if (profiles[0].CatId != Guids.Consts.TfcatTipKeyboard) { continue; } if ((profiles[0].Flags & TfIppFlags.Enabled) == 0) { continue; } if (profiles[0].ProfileType == TfProfileType.Illegal) { continue; } LayoutName layoutName; if (profiles[0].Hkl == IntPtr.Zero) { try { layoutName = new LayoutName(inputLanguage.LayoutName, ProcessorProfiles.GetLanguageProfileDescription(ref profiles[0].ClsId, profiles[0].LangId, ref profiles[0].GuidProfile), profiles[0]); } catch { // this exception has happened in testing, doesn't seem to be anything we can do // except just ignore this keyboard continue; } returnedLanguage = true; yield return(layoutName); } else { layoutName = WinKeyboardUtils.GetLayoutNameEx(profiles[0].Hkl); if (layoutName.Name != string.Empty) { layoutName.Profile = profiles[0]; returnedLanguage = true; yield return(layoutName); } } } if (!returnedLanguage) { yield return(new LayoutName(inputLanguage.LayoutName, culture.DisplayName)); } }
private static bool InputProcessorProfilesEqual(TfInputProcessorProfile profile1, TfInputProcessorProfile profile2) { // Don't compare Flags - they can be different and it's still the same profile return profile1.ProfileType == profile2.ProfileType && profile1.LangId == profile2.LangId && profile1.ClsId == profile2.ClsId && profile1.GuidProfile == profile2.GuidProfile && profile1.CatId == profile2.CatId && profile1.HklSubstitute == profile2.HklSubstitute && profile1.Caps == profile2.Caps && profile1.Hkl == profile2.Hkl; }
internal WinKeyboardDescription(string keyboardId, string localizedKeyboardName, string inputLanguageLayoutName, string cultureName, bool isAvailable, IInputLanguage inputLanguage, WinKeyboardAdaptor engine, TfInputProcessorProfile profile) : base(keyboardId, localizedKeyboardName, inputLanguageLayoutName, cultureName, isAvailable, engine.SwitchingAdaptor) { InputLanguage = inputLanguage; _localizedName = localizedKeyboardName; ConversionMode = (int)(Win32.IME_CMODE.NATIVE | Win32.IME_CMODE.SYMBOL); _useNfcContext = IsKeymanKeyboard(cultureName); InputProcessorProfile = profile; }
private void GetInputMethods() { IEnumerable <Tuple <TfInputProcessorProfile, ushort, IntPtr> > imes; if (ProfileMgr != null) { // Windows >= Vista imes = GetInputMethodsThroughTsf(); } else { // Windows XP imes = GetInputMethodsThroughWinApi(); } var allKeyboards = KeyboardController.Instance.Keyboards; Dictionary <string, WinKeyboardDescription> curKeyboards = allKeyboards.OfType <WinKeyboardDescription>().ToDictionary(kd => kd.Id); foreach (Tuple <TfInputProcessorProfile, ushort, IntPtr> ime in imes) { TfInputProcessorProfile profile = ime.Item1; ushort langId = ime.Item2; IntPtr hkl = ime.Item3; CultureInfo culture; string locale; string cultureName; try { culture = new CultureInfo(langId); cultureName = culture.DisplayName; locale = culture.Name; } catch (CultureNotFoundException) { // This can happen for old versions of Keyman that created a custom culture that is invalid to .Net. // Also see http://stackoverflow.com/a/24820530/4953232 culture = new CultureInfo("en-US"); cultureName = "[Unknown Language]"; locale = "en-US"; } try { LayoutName layoutName; if (profile.Hkl == IntPtr.Zero && profile.ProfileType != TfProfileType.Illegal) { layoutName = new LayoutName(ProcessorProfiles.GetLanguageProfileDescription( ref profile.ClsId, profile.LangId, ref profile.GuidProfile)); } else { layoutName = GetLayoutNameEx(hkl); } string id = GetId(layoutName.Name, locale); WinKeyboardDescription existingKeyboard; if (curKeyboards.TryGetValue(id, out existingKeyboard)) { if (!existingKeyboard.IsAvailable) { existingKeyboard.SetIsAvailable(true); existingKeyboard.InputProcessorProfile = profile; existingKeyboard.SetLocalizedName(GetDisplayName(layoutName.LocalizedName, cultureName)); } curKeyboards.Remove(id); } else { // Prevent a keyboard with this id from being registered again. // Potentially, id's are duplicated. e.g. A Keyman keyboard linked to a windows one. // For now we simply ignore this second registration. // A future enhancement would be to include knowledge of the driver in the Keyboard definition so // we could choose the best one to register. KeyboardDescription keyboard; if (!allKeyboards.TryGet(id, out keyboard)) { KeyboardController.Instance.Keyboards.Add( new WinKeyboardDescription(id, GetDisplayName(layoutName.Name, cultureName), layoutName.Name, locale, true, new InputLanguageWrapper(culture, hkl, layoutName.Name), this, GetDisplayName(layoutName.LocalizedName, cultureName), profile)); } } } catch (COMException) { // this can happen when the user changes the language associated with a // Keyman keyboard (LT-16172) } } foreach (WinKeyboardDescription existingKeyboard in curKeyboards.Values) { existingKeyboard.SetIsAvailable(false); } }