FontContent ProcessFont(LocaleSource input, KeyboardLayoutContent keyboardLayoutContent, ContentProcessorContext context) { // Get all code points used by this keyboard layout List <char> codePoints = new List <char>(); VirtualKeyContent[] keys = keyboardLayoutContent.Keys; foreach (VirtualKeyContent key in keys) { if (key == null) { continue; } foreach (VirtualKeyValue value in key.ShiftStates) { if (value != VirtualKeyValue.Empty) { GetCodePointsFromCharacters(value.Characters.ToCharArray(), codePoints); } } } foreach (DeadKey deadKey in keyboardLayoutContent.DeadKeys.Values) { GetCodePointsFromCharacters(deadKey.CombinedCharacters, codePoints); } codePoints.Sort(); context.Logger.LogMessage("Keyboard layout for locale {0} requires {1} code points", input.CultureInfo.Name, codePoints.Count); FontSource fs = new FontSource(input.FontName, codePoints.ToArray()); return(context.Convert <FontSource, FontContent>(fs, "FontProcessor")); }
public override LocaleContent Process(LocaleSource input, ContentProcessorContext context) { KeyboardLayoutContent klc = ProcessKeyboardLayout(input, context); FontContent font = ProcessFont(input, klc, context); return(new LocaleContent( input.CultureInfo, klc, font )); }
internal static void FillKeyState(KeyboardLayoutContent kbl, KeysEx[] lpKeyState, ShiftState ss, bool fCapsLock) { lpKeyState[(int)KeysEx.VK_SHIFT] = (((ss & ShiftState.Shft) != 0) ? (KeysEx)0x80 : (KeysEx)0x00); lpKeyState[(int)KeysEx.VK_CONTROL] = (((ss & ShiftState.Ctrl) != 0) ? (KeysEx)0x80 : (KeysEx)0x00); lpKeyState[(int)KeysEx.VK_MENU] = (((ss & ShiftState.Menu) != 0) ? (KeysEx)0x80 : (KeysEx)0x00); if (kbl.SpecialShiftVk != KeysEx.None) { // The Xxxx key has been assigned, so let's include it lpKeyState[(int)kbl.SpecialShiftVk] = (((ss & ShiftState.Spcl) != 0) ? (KeysEx)0x80 : (KeysEx)0x00); } lpKeyState[(int)KeysEx.VK_CAPITAL] = (fCapsLock ? (KeysEx)0x01 : (KeysEx)0x00); }
public static void TestImport(int localeId) { String lid = String.Format("{0:x8}", localeId); KeyboardLayoutSource kls = new KeyboardLayoutSource(lid); KeyboardLayoutProcessor klp = new KeyboardLayoutProcessor(); KeyboardLayoutContent klc = klp.Process(kls, null); VirtualKey vk = klc.Keys[(int)KeysEx.VK_Z].VirtualKey; byte[] buffer = new byte[1024]; MemoryStream ms = new MemoryStream(buffer); BinaryWriter bw = new BinaryWriter(ms); foreach (VirtualKeyValue value in vk.ShiftStates) { bw.Write(value.Characters); System.Diagnostics.Debug.WriteLine(value.Characters); } bw.Close(); }
internal LocaleContent(CultureInfo cultureInfo, KeyboardLayoutContent keyboardLayout, FontContent font) { this.cultureInfo = cultureInfo; this.keyboardLayout = keyboardLayout; this.font = font; }
/// <summary> /// /// </summary> /// <param name="iKeyDead">The index into the VirtualKey of the dead key</param> /// <param name="shiftStateDead">The shiftstate that contains the dead key</param> /// <param name="lpKeyStateDead">The key state for the dead key</param> /// <param name="rgKey">Our array of dead keys</param> /// <param name="fCapsLock">Was the caps lock key pressed?</param> /// <param name="hkl">The keyboard layout</param> /// <returns></returns> internal static DeadKey ProcessDeadKey(KeyboardLayoutContent kbl, uint iKeyDead, ShiftState shiftStateDead, KeysEx[] lpKeyStateDead, VirtualKeyContent[] rgKey, bool fCapsLock, IntPtr hkl) { KeysEx[] lpKeyState = new KeysEx[256]; String dkShiftState = rgKey[iKeyDead].GetShiftState(shiftStateDead, fCapsLock).Characters; DeadKey deadKey = new DeadKey(dkShiftState[0]); for (uint iKey = 0; iKey < rgKey.Length; iKey++) { if (rgKey[iKey] != null) { StringBuilder sbBuffer = new StringBuilder(10); // Scratchpad we use many places for (ShiftState ss = ShiftState.Base; ss <= kbl.MaxShiftState; ss++) { int rc = 0; if (ss == ShiftState.Menu || ss == ShiftState.ShftMenu) { // Alt and Shift+Alt don't work, so skip them continue; } for (int caps = 0; caps <= 1; caps++) { // First the dead key while (rc >= 0) { // We know that this is a dead key coming up, otherwise // this function would never have been called. If we do // *not* get a dead key then that means the state is // messed up so we run again and again to clear it up. // Risk is technically an infinite loop but per Hiroyama // that should be impossible here. rc = NativeMethods.User32.ToUnicodeEx((uint)rgKey[iKeyDead].VK, rgKey[iKeyDead].SC, lpKeyStateDead, sbBuffer, sbBuffer.Capacity, 0, hkl); } // Now fill the key state for the potential base character FillKeyState(kbl, lpKeyState, ss, (caps != 0)); sbBuffer = new StringBuilder(10); rc = NativeMethods.User32.ToUnicodeEx((uint)rgKey[iKey].VK, rgKey[iKey].SC, lpKeyState, sbBuffer, sbBuffer.Capacity, 0, hkl); if (rc == 1) { // That was indeed a base character for our dead key. // And we now have a composite character. Let's run // through one more time to get the actual base // character that made it all possible? char combchar = sbBuffer[0]; sbBuffer = new StringBuilder(10); rc = NativeMethods.User32.ToUnicodeEx((uint)rgKey[iKey].VK, rgKey[iKey].SC, lpKeyState, sbBuffer, sbBuffer.Capacity, 0, hkl); char basechar = sbBuffer[0]; if (deadKey.DeadCharacter == combchar) { // Since the combined character is the same as the dead key, // we must clear out the keyboard buffer. ClearKeyboardBuffer((uint)KeysEx.VK_DECIMAL, rgKey[(uint)KeysEx.VK_DECIMAL].SC, hkl); } if ((((ss == ShiftState.Ctrl) || (ss == ShiftState.ShftCtrl)) && (char.IsControl(basechar))) || (basechar.Equals(combchar))) { // ToUnicodeEx has an internal knowledge about those // VK_A ~ VK_Z keys to produce the control characters, // when the conversion rule is not provided in keyboard // layout files // Additionally, dead key state is lost for some of these // character combinations, for unknown reasons. // Therefore, if the base character and combining are equal, // and its a CTRL or CTRL+SHIFT state, and a control character // is returned, then we do not add this "dead key" (which // is not really a dead key). continue; } if (!deadKey.ContainsBaseCharacter(basechar)) { deadKey.AddDeadKeyRow(basechar, combchar); } } else if (rc > 1) { // Not a valid dead key combination, sorry! We just ignore it. } else if (rc < 0) { // It's another dead key, so we ignore it (other than to flush it from the state) ClearKeyboardBuffer((uint)KeysEx.VK_DECIMAL, rgKey[(uint)KeysEx.VK_DECIMAL].SC, hkl); } } } } } return(deadKey); }