using Gma.System.MouseKeyHook; using System; using System.Collections; using System.Collections.Generic; using System.Windows.Forms; using UnityEngine; using UnityEngine.EventSystems; [RequireComponent(typeof(BaseInputModule))] public class GlobalMKHookInput : BaseInput { public bool ignoreAppFocus = false; IKeyboardMouseEvents m_GlobalHook; bool focus = false; [SerializeField] bool verbose = false; public override int touchCount { get { return base.touchCount + TUIOManager.Instance.touches.Count; } } public override bool touchSupported { get { return true; } } private bool control = false; private bool shift = false; private string inputtext; //Dictionary index_stamp = new Dictionary(); //Dictionary index_touch = new Dictionary(); //Dictionary index_prev_phase = new Dictionary(); //public float touchDelay = 0.1f; //Dictionary tuio_touches = new Dictionary(); public override Touch GetTouch(int index) { if (index < base.touchCount) { return base.GetTouch(index); } else { index -= base.touchCount; #if true int[] keys = new int[TUIOManager.Instance.touches.Count]; TUIOManager.Instance.touches.Keys.CopyTo(keys, 0); return TUIOManager.Instance.touches[keys[index]]; #else int[] keys = new int[tuio_touches.Count]; tuio_touches.Keys.CopyTo(keys, 0); return tuio_touches[keys[index]]; #endif } } new void Awake() { m_GlobalHook = Hook.GlobalEvents(); m_GlobalHook.KeyDown += GlobalHookKeyDown; m_GlobalHook.KeyPress += GlobalHookKeyPress; m_GlobalHook.KeyUp += GlobalHookKeyUp; } new void OnDestroy() { m_GlobalHook.KeyDown -= GlobalHookKeyDown; m_GlobalHook.KeyPress -= GlobalHookKeyPress; m_GlobalHook.KeyUp -= GlobalHookKeyUp; m_GlobalHook.Dispose(); } private void OnApplicationFocus(bool focus) { this.focus = focus; } private void LateUpdate() { keys.Clear(); #if false // update index_stamp { // collect missing touch id List candidates = new List(); List remove_candidates = new List(); foreach (var id in index_stamp.Keys) { if (TUIOManager.Instance.touches.ContainsKey(id) == false) candidates.Add(id); } // check missing id is Ended or set it foreach (var id in candidates) { var t = index_touch[id]; if (t.phase == TouchPhase.Ended) { remove_candidates.Add(id); } else { t.phase = TouchPhase.Ended; index_touch[id] = t; } } // remove ended id foreach (var id in remove_candidates) { index_stamp.Remove(id); index_touch.Remove(id); } // check current id int[] indices = new int[TUIOManager.Instance.touches.Keys.Count]; TUIOManager.Instance.touches.Keys.CopyTo(indices, 0); for (int i = 0; i < indices.Length; i++) { int id = indices[i]; Touch t = TUIOManager.Instance.touches[indices[i]]; // new id if (index_stamp.ContainsKey(id) == false) { t.phase = TouchPhase.Stationary; index_stamp.Add(id, Time.time); index_touch.Add(id, t); } else { t.phase = index_touch[id].phase; index_touch[id] = t; } } // update phase by time stamp indices = new int[index_touch.Keys.Count]; index_touch.Keys.CopyTo(indices, 0); tuio_touches.Clear(); List valid_phases = new List() { TouchPhase.Began, TouchPhase.Moved, TouchPhase.Ended }; foreach (var i in indices) { float dt = Time.time - index_stamp[i]; Touch t = index_touch[i]; TouchPhase tp = t.phase; if (tp == TouchPhase.Stationary) { if (dt > touchDelay) { tp = TouchPhase.Began; } } else if (tp == TouchPhase.Began) { tp = TouchPhase.Moved; } t.phase = tp; index_touch[i] = t; if (valid_phases.Contains(t.phase)) tuio_touches.Add(i, t); } } #endif } public override bool GetButtonDown(string buttonName) { if (focus && !ignoreAppFocus) return base.GetButtonDown(buttonName); else return CheckButtonDown(buttonName); } private bool CheckButtonDown(string buttonName) { foreach (Keys k in keys) { if(KeyConvertion.ContainsKey(k)) { if (KeyConvertion[k].ToString() == buttonName) return true; } } return false; } private static Queue m_events = new Queue(); HashSet keys = new HashSet(); private void GlobalHookKeyDown(object sender, KeyEventArgs e) { if (verbose) Debug.Log("GlobalHookKeyDown: " + ToString(e)); Event m_event = ToEvent(e, EventType.KeyDown); if (m_event != null) { m_events.Enqueue(m_event); if(m_event.character != char.MinValue) inputtext += m_event.character.ToString(); if(m_event.keyCode == KeyCode.Return) { print(inputtext); inputtext = ""; } } keys.Add(e.KeyCode); } private void GlobalHookKeyPress(object sender, KeyPressEventArgs e) { //Debug.Log("SystemTime:" + DateTime.Now + ";keyboard:" + e.KeyChar + ";"); } private void GlobalHookKeyUp(object sender, KeyEventArgs e) { if (verbose) Debug.Log("GlobalHookKeyUp: " + ToString(e)); Event m_event = ToEvent(e, EventType.KeyUp); if (m_event != null) { m_events.Enqueue(m_event); } keys.Remove(e.KeyCode); } public static bool PopEvents(ref Event _event) { if (m_events.Count != 0) { _event = m_events.Dequeue(); return true; } else return false; } string ToString(KeyEventArgs e) { return "[Key Down] KeyCode: " + e.KeyCode + " KeyData: " + e.KeyData + " Modifiers: " + e.Modifiers; } Event ToEvent(KeyEventArgs e, EventType keytype) { Event keyEvent = new Event(); keyEvent.type = keytype; keyEvent.shift = shift; keyEvent.control = control; if (EngKeywords.ContainsKey(e.KeyCode)) { keyEvent.keyCode = EngKeywords[e.KeyCode]; char[] keystring = e.KeyCode.ToString().ToCharArray(0, 1); if (shift) { keystring[0] = char.ToUpper(keystring[0]); } else { keystring[0] = char.ToLower(keystring[0]); } keyEvent.character = keystring[0]; return keyEvent; } else if(AlphaNums.ContainsKey(e.KeyCode)) { keyEvent.keyCode = AlphaNums[e.KeyCode]; char[] keystring = e.KeyCode.ToString().ToCharArray(1,1); keyEvent.character = keystring[0]; keyEvent.numeric = true; return keyEvent; } else if (NumPads.ContainsKey(e.KeyCode)) { keyEvent.keyCode = NumPads[e.KeyCode]; char[] keystring = e.KeyCode.ToString().ToCharArray(6,1); keyEvent.character = keystring[0]; keyEvent.numeric = true; return keyEvent; } else if (Modifierkeys.ContainsKey(e.KeyCode)) { keyEvent.keyCode = Modifierkeys[e.KeyCode]; if (e.KeyCode == Keys.LShiftKey || e.KeyCode == Keys.RShiftKey) { if(keytype == EventType.KeyDown) shift = true; else if(keytype == EventType.KeyUp) shift = false; } if (e.KeyCode == Keys.LControlKey || e.KeyCode == Keys.RControlKey) { if (keytype == EventType.KeyDown) control = true; else if (keytype == EventType.KeyUp) control = false; } keyEvent.shift = shift; keyEvent.control = control; return keyEvent; } else if (SpecialKeywords.ContainsKey(e.KeyCode)) { keyEvent.keyCode = SpecialKeywords[e.KeyCode]; char keystring; if (shift) keystring = SpecialKeywordsShift[e.KeyCode]; else keystring = SpecialKeywordsnoShift[e.KeyCode]; keyEvent.character = keystring; return keyEvent; } return null; } private static readonly IDictionary EngKeywords = new Dictionary { { Keys.A, KeyCode.A}, { Keys.B, KeyCode.B}, { Keys.C, KeyCode.C}, { Keys.D, KeyCode.D}, { Keys.E, KeyCode.E}, { Keys.F, KeyCode.F}, { Keys.G, KeyCode.G}, { Keys.H, KeyCode.H}, { Keys.I, KeyCode.I}, { Keys.J, KeyCode.J}, { Keys.K, KeyCode.K}, { Keys.L, KeyCode.L}, { Keys.M, KeyCode.M}, { Keys.N, KeyCode.N}, { Keys.O, KeyCode.O}, { Keys.P, KeyCode.P}, { Keys.Q, KeyCode.Q}, { Keys.R, KeyCode.R}, { Keys.S, KeyCode.S}, { Keys.T, KeyCode.T}, { Keys.U, KeyCode.U}, { Keys.V, KeyCode.V}, { Keys.W, KeyCode.W}, { Keys.X, KeyCode.X}, { Keys.Y, KeyCode.Y}, { Keys.Z, KeyCode.Z}, }; private static readonly IDictionary SpecialKeywords = new Dictionary { { Keys.OemPipe, KeyCode.Backslash}, { Keys.Divide, KeyCode.KeypadDivide}, { Keys.OemSemicolon, KeyCode.Colon }, { Keys.OemQuestion, KeyCode.Question }, { Keys.OemPeriod, KeyCode.Period }, { Keys.OemMinus, KeyCode.Minus }, { Keys.Oem3, KeyCode.BackQuote }, { Keys.Oem4, KeyCode.LeftBracket }, { Keys.OemCloseBrackets, KeyCode.RightBracket }, { Keys.Oemplus, KeyCode.Equals }, }; private static readonly IDictionary SpecialKeywordsnoShift = new Dictionary { { Keys.OemPipe, '\''}, { Keys.Divide, '/'}, { Keys.OemSemicolon, ';'}, { Keys.OemQuestion, '/'}, { Keys.OemPeriod, '.' }, { Keys.OemMinus, '-' }, { Keys.Oem3, '`' }, { Keys.Oem4, '[' }, { Keys.OemCloseBrackets, ']' }, { Keys.Oemplus, '=' }, }; private static readonly IDictionary SpecialKeywordsShift = new Dictionary { { Keys.OemPipe, '\\'}, { Keys.Divide, '/'}, { Keys.OemSemicolon, ':'}, { Keys.OemQuestion, '?'}, { Keys.OemPeriod, '>' }, { Keys.OemMinus, '_' }, { Keys.Oem3, '~' }, { Keys.Oem4, '{' }, { Keys.OemCloseBrackets, '}' }, { Keys.Oemplus, '+' }, }; private static readonly IDictionary AlphaNums = new Dictionary { { Keys.D0, KeyCode.Alpha0 }, { Keys.D1, KeyCode.Alpha1 }, { Keys.D2, KeyCode.Alpha2 }, { Keys.D3, KeyCode.Alpha3 }, { Keys.D4, KeyCode.Alpha4 }, { Keys.D5, KeyCode.Alpha5 }, { Keys.D6, KeyCode.Alpha6 }, { Keys.D7, KeyCode.Alpha7 }, { Keys.D8, KeyCode.Alpha8 }, { Keys.D9, KeyCode.Alpha9 }, }; private static readonly IDictionary NumPads = new Dictionary { { Keys.NumPad0, KeyCode.Keypad0 }, { Keys.NumPad1, KeyCode.Keypad1 }, { Keys.NumPad2, KeyCode.Keypad2 }, { Keys.NumPad3, KeyCode.Keypad3 }, { Keys.NumPad4, KeyCode.Keypad4 }, { Keys.NumPad5, KeyCode.Keypad5 }, { Keys.NumPad6, KeyCode.Keypad6 }, { Keys.NumPad7, KeyCode.Keypad7 }, { Keys.NumPad8, KeyCode.Keypad8 }, { Keys.NumPad9, KeyCode.Keypad9 }, }; private static readonly IDictionary Modifierkeys = new Dictionary { { Keys.PageUp, KeyCode.PageUp}, { Keys.PageDown, KeyCode.PageDown}, { Keys.End, KeyCode.End}, { Keys.Home, KeyCode.Home}, { Keys.Return, KeyCode.Return}, { Keys.LShiftKey, KeyCode.LeftShift}, { Keys.RShiftKey, KeyCode.RightShift}, { Keys.LControlKey, KeyCode.LeftControl}, { Keys.RControlKey, KeyCode.RightControl} }; private static readonly IDictionary KeyConvertion = new Dictionary { { Keys.Up , KeyCode.UpArrow }, { Keys.Down , KeyCode.DownArrow }, { Keys.Right, KeyCode.RightArrow}, { Keys.Left, KeyCode.LeftArrow}, { Keys.D0, KeyCode.Alpha0 }, { Keys.D1, KeyCode.Alpha1 }, { Keys.D2, KeyCode.Alpha2 }, { Keys.D3, KeyCode.Alpha3 }, { Keys.D4, KeyCode.Alpha4 }, { Keys.D5, KeyCode.Alpha5 }, { Keys.D6, KeyCode.Alpha6 }, { Keys.D7, KeyCode.Alpha7 }, { Keys.D8, KeyCode.Alpha8 }, { Keys.D9, KeyCode.Alpha9 }, { Keys.NumPad0, KeyCode.Keypad0 }, { Keys.NumPad1, KeyCode.Keypad1 }, { Keys.NumPad2, KeyCode.Keypad2 }, { Keys.NumPad3, KeyCode.Keypad3 }, { Keys.NumPad4, KeyCode.Keypad4 }, { Keys.NumPad5, KeyCode.Keypad5 }, { Keys.NumPad6, KeyCode.Keypad6 }, { Keys.NumPad7, KeyCode.Keypad7 }, { Keys.NumPad8, KeyCode.Keypad8 }, { Keys.NumPad9, KeyCode.Keypad9 }, { Keys.F1, KeyCode.F1 }, { Keys.F2, KeyCode.F2 }, { Keys.F3, KeyCode.F3 }, { Keys.F4, KeyCode.F4 }, { Keys.F5, KeyCode.F5 }, { Keys.F6, KeyCode.F6 }, { Keys.F7, KeyCode.F7 }, { Keys.F8, KeyCode.F8 }, { Keys.F9, KeyCode.F9 }, { Keys.F10, KeyCode.F10 }, { Keys.F11, KeyCode.F11 }, { Keys.F12, KeyCode.F12 }, //{ Keys.Prior, KeyCode.PageUp}, { Keys.PageUp, KeyCode.PageUp}, //{ Keys.Next, KeyCode.PageDown}, { Keys.PageDown, KeyCode.PageDown}, { Keys.End, KeyCode.End}, { Keys.Home, KeyCode.Home}, { Keys.A, KeyCode.A}, { Keys.B, KeyCode.B}, { Keys.C, KeyCode.C}, { Keys.D, KeyCode.D}, { Keys.E, KeyCode.E}, { Keys.F, KeyCode.F}, { Keys.G, KeyCode.G}, { Keys.H, KeyCode.H}, { Keys.I, KeyCode.I}, { Keys.J, KeyCode.J}, { Keys.K, KeyCode.K}, { Keys.L, KeyCode.L}, { Keys.M, KeyCode.M}, { Keys.N, KeyCode.N}, { Keys.O, KeyCode.O}, { Keys.P, KeyCode.P}, { Keys.Q, KeyCode.Q}, { Keys.R, KeyCode.R}, { Keys.S, KeyCode.S}, { Keys.T, KeyCode.T}, { Keys.U, KeyCode.U}, { Keys.V, KeyCode.V}, { Keys.W, KeyCode.W}, { Keys.X, KeyCode.X}, { Keys.Y, KeyCode.Y}, { Keys.Z, KeyCode.Z}, }; }