/// <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));
            }
        }
示例#7
0
		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);
            }
        }