public override void Update(GameTime gameTime) { base.Update(gameTime); // Get current keystroke and check if this is a new keystroke or // if it is a repeated one. KeyboardState state = Keyboard.GetState(); VirtualKeyValue[] keystroke = keyboardLayout.ProcessKeys(state); Keys[] filteredStroke = keyboardLayout.FilteredPressedKeys; bool isNewStroke = true; if (previousStroke != null) { // Check scan codes to handle modifier+char to char transitions. // If two or more keys are pressed, the last one is used and when // this key is released, no keystroke is generated. int newKeyIndex = -1; int i; int j = 0; for (i = 0; i < filteredStroke.Length; i++) { // KeyboardLayout.FilteredPressedKeys is sorted while (j < previousStroke.Length && previousStroke[j] < filteredStroke[i]) { j++; } if (j >= previousStroke.Length) { newKeyIndex = i; break; } else if (previousStroke[j] > filteredStroke[i]) { newKeyIndex = i; } } if (newKeyIndex > -1) { isNewStroke = currentKeyValue != keystroke[newKeyIndex]; currentKeyValue = keystroke[newKeyIndex]; } else { isNewStroke = false; if (keystroke.Length == 0) { currentKeyValue = VirtualKeyValue.Empty; } } } for (int i = 0; i < keyStates.Length; i++) { keyStates[i] = KeyStateFlags.Up; } // If the keystroke is a new stroke, reset start time and update // key state flags to notify that the key was just released if (isNewStroke == true) { strokeStartTime = gameTime.TotalGameTime.TotalMilliseconds; repeatTimeCount = -1; if (previousStroke != null) { foreach (Keys key in previousStroke) { keyStates[(int)key] = KeyStateFlags.Released; } } } // Apply delay and repeat-speed to stroke age double dt = gameTime.TotalGameTime.TotalMilliseconds - strokeStartTime; bool doSetString = false; KeyStateFlags newKeyStateFlags = KeyStateFlags.Down; if (dt <= float.Epsilon) { // First stroke doSetString = true; } else if (repeatTimeCount == -1 && delayTime - dt < float.Epsilon) { // Repeat delay time reached doSetString = true; repeatTimeCount = 0; newKeyStateFlags |= KeyStateFlags.Repeat; } else if (repeatTimeCount > -1) { dt -= delayTime; // Count stroke repeats int i; for (i = 0; dt > 0; i++) { dt -= repeatTime; } if (i > repeatTimeCount) { doSetString = true; repeatTimeCount++; } newKeyStateFlags |= KeyStateFlags.Repeat; } // Build the current key strokes output characters = ""; if (doSetString == true && keystroke.Length > 0) { VirtualKeyValue keyValue = currentKeyValue; if (deadKey != null) { char baseChar = keyValue.Characters[0]; if (deadKey.ContainsBaseCharacter(baseChar) == true) { characters = deadKey.GetCombinedCharacter(baseChar).ToString(); } else { characters = String.Format("{0}{1}", deadKey.DeadCharacter, baseChar); } deadKey = null; } else if (keyValue.IsDeadKey == true) { keyboardLayout.DeadKeys.TryGetValue(keyValue.Characters[0], out deadKey); } else if (keyValue.Characters != null && Char.IsControl(keyValue.Characters, 0) == false) { // Add non-control characters only characters = keyValue.Characters; } } if (doSetString == true && filteredStroke.Length > 0) { // Update key state flags foreach (Keys key in filteredStroke) { keyStates[(int)key] = newKeyStateFlags; } } previousStroke = filteredStroke; }
internal String LayoutRow(KeyboardLayoutContent kbl) { StringBuilder sbRow = new StringBuilder(); // First, get the SC/VK info stored sbRow.Append(String.Format("{0:x2}\t{1:x2} - {2}", SC, (byte)VK, ((KeysEx)VK).ToString().PadRight(13))); // Now the CAPSLOCK value int capslock = 0 | (IsCapsEqualToShift ? 1 : 0) | (IsSGCaps ? 2 : 0) | (IsAltGrCapsEqualToAltGrShift ? 4 : 0) | (IsSpecialGrCapsEqualToSpecialShift ? 8 : 0); sbRow.Append(String.Format("\t{0}", capslock)); for (ShiftState ss = 0; ss <= kbl.MaxShiftState; ss++) { if (ss == ShiftState.Menu || ss == ShiftState.ShftMenu) { // Alt and Shift+Alt ain't supported in keyboard layouts, so skip them continue; } for (int caps = 0; caps <= 1; caps++) { VirtualKeyValue vkv = GetShiftState(ss, (caps == 1)); if (vkv.Characters.Length == 0) { // No character assigned here, put in -1. sbRow.Append("\t -1"); } else if ((caps == 1) && vkv == GetShiftState(ss, (caps == 0))) { // Its a CAPS LOCK state and the assigned character(s) are // identical to the non-CAPS LOCK state. Put in a MIDDLE DOT. sbRow.Append("\t ."); //sbRow.Append("\t \u00b7"); } else if (vkv.IsDeadKey == true) { // It's a dead key, append an @ sign. sbRow.Append(String.Format("\t{0:x4}@", ((ushort)vkv.Characters[0]))); } else { // It's some characters; put 'em in there. StringBuilder sbChar = new StringBuilder((5 * vkv.Characters.Length) + 1); for (int ich = 0; ich < vkv.Characters.Length; ich++) { sbChar.Append(((ushort)vkv.Characters[ich]).ToString("x4")); sbChar.Append(' '); } sbRow.Append(String.Format("\t{0}", sbChar.ToString(0, sbChar.Length - 1))); } } } return(sbRow.ToString()); }
void WriteVirtualKeyValue(ContentWriter output, VirtualKeyValue value) { output.Write(value.Characters); output.Write(value.IsDeadKey); }
internal void SetShiftState(ShiftState shiftState, String value, bool isDeadKey, bool capsLock) { shiftStateValues[(uint)shiftState * 2 + (capsLock ? 1 : 0)] = new VirtualKeyValue(value, isDeadKey); }