Пример #1
0
        private LayoutName GetBestAvailableKeyboardName(InputLanguage inputLanguage)
        {
            try
            {
                var profilesEnumerator             = ProfileManager.EnumProfiles((short)inputLanguage.Culture.KeyboardLayoutId);
                TfInputProcessorProfile[] profiles = new TfInputProcessorProfile[1];
                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].Hkl == IntPtr.Zero && profiles[0].ProfileType != TfProfileType.Illegal)
                    {
                        return(new LayoutName(inputLanguage.LayoutName,
                                              ProcessorProfiles.GetLanguageProfileDescription(ref profiles[0].ClsId, profiles[0].LangId,
                                                                                              ref profiles[0].GuidProfile)));
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine($"Error looking up keyboards for language {inputLanguage.Culture.Name} - {(short)inputLanguage.Culture.KeyboardLayoutId}");
            }
            return(new LayoutName(inputLanguage.LayoutName, inputLanguage.Culture.DisplayName));
        }
Пример #2
0
        private IEnumerable <LayoutName> GetAvailableKeyboardNames(InputLanguage inputLanguage)
        {
            IEnumTfInputProcessorProfiles profilesEnumerator;

            try
            {
                profilesEnumerator = ProfileManager.EnumProfiles((short)inputLanguage.Culture.KeyboardLayoutId);
            }
            catch (Exception e)
            {
                Debug.WriteLine($"Error looking up keyboards for language {inputLanguage.Culture.Name} - {(short)inputLanguage.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)
                {
                    returnedLanguage = true;
                    layoutName       = new LayoutName(inputLanguage.LayoutName,
                                                      ProcessorProfiles.GetLanguageProfileDescription(ref profiles[0].ClsId, profiles[0].LangId,
                                                                                                      ref profiles[0].GuidProfile), profiles[0]);
                    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, inputLanguage.Culture.DisplayName));
            }
        }
Пример #3
0
        private WinKeyboardDescription ActivateKeyboard(WinKeyboardDescription winKeyboard)
        {
            try
            {
                if (UseWindowsApiForKeyboardSwitching(winKeyboard))
                {
                    // Win XP with regular keyboard, or TSF disabled
                    Win32.ActivateKeyboardLayout(new HandleRef(this, winKeyboard.InputLanguage.Handle), 0);
                    return(winKeyboard);
                }

                var profile = winKeyboard.InputProcessorProfile;
                if ((profile.Flags & TfIppFlags.Enabled) == 0)
                {
                    return(winKeyboard);
                }

                ProcessorProfiles.ChangeCurrentLanguage(profile.LangId);
                if (ProfileMgr == null)
                {
                    // Win XP with TIP (TSF Input Processor)
                    ProcessorProfiles.ActivateLanguageProfile(ref profile.ClsId, profile.LangId,
                                                              ref profile.GuidProfile);
                }
                else
                {
                    // Windows >= Vista with either TIP or regular keyboard
                    ProfileMgr.ActivateProfile(profile.ProfileType, profile.LangId,
                                               ref profile.ClsId, ref profile.GuidProfile, profile.Hkl,
                                               TfIppMf.DontCareCurrentInputLanguage);
                }
            }
            catch (ArgumentException)
            {
                // throws exception for non-supported culture, though seems to set it OK.
            }
            catch (COMException e)
            {
                var profile = winKeyboard.InputProcessorProfile;
                var msg     = string.Format("Got COM exception trying to activate IM:" + Environment.NewLine +
                                            "LangId={0}, clsId={1}, hkl={2}, guidProfile={3}, flags={4}, type={5}, catId={6}",
                                            profile.LangId, profile.ClsId, profile.Hkl, profile.GuidProfile, profile.Flags, profile.ProfileType, profile.CatId);
                throw new ApplicationException(msg, e);
            }
            return(winKeyboard);
        }
Пример #4
0
        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 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);
            }
        }