diff --git a/Source/OpenTK/Platform/MacOS/HIDInput.cs b/Source/OpenTK/Platform/MacOS/HIDInput.cs index b423ab97..a743954d 100755 --- a/Source/OpenTK/Platform/MacOS/HIDInput.cs +++ b/Source/OpenTK/Platform/MacOS/HIDInput.cs @@ -59,16 +59,29 @@ namespace OpenTK.Platform.MacOS class MouseData { + public IntPtr Id; public MouseState State; + + public MouseData(IntPtr id) + { + Id = id; + } } class KeyboardData { + public IntPtr Id; public KeyboardState State; + + public KeyboardData(IntPtr id) + { + Id = id; + } } class JoystickData { + public IntPtr Id; public string Name; public Guid Guid; public JoystickState State; @@ -77,6 +90,11 @@ namespace OpenTK.Platform.MacOS readonly public Dictionary Elements = new Dictionary(); + public JoystickData(IntPtr id) + { + Id = id; + } + public void AddElement(JoystickElement e) { if (!Elements.ContainsKey(e.Cookie)) @@ -145,20 +163,12 @@ namespace OpenTK.Platform.MacOS IOHIDManagerRef hidmanager; - readonly Dictionary MouseDevices = - new Dictionary(new IntPtrEqualityComparer()); - readonly Dictionary MouseIndexToDevice = - new Dictionary(); - - readonly Dictionary KeyboardDevices = - new Dictionary(new IntPtrEqualityComparer()); - readonly Dictionary KeyboardIndexToDevice = - new Dictionary(); - - readonly Dictionary JoystickDevices = - new Dictionary(new IntPtrEqualityComparer()); - readonly Dictionary JoystickIndexToDevice = - new Dictionary(); + readonly DeviceCollection MouseDevices = + new DeviceCollection(); + readonly DeviceCollection KeyboardDevices = + new DeviceCollection(); + readonly DeviceCollection JoystickDevices = + new DeviceCollection(); readonly CFRunLoop RunLoop; readonly CFString InputLoopMode = CF.RunLoopModeDefault; @@ -393,22 +403,27 @@ namespace OpenTK.Platform.MacOS try { bool recognized = false; + long id = device.ToInt64(); - if (MouseDevices.ContainsKey(device)) + MouseData mouse; + KeyboardData keyboard; + JoystickData joystick; + + if (MouseDevices.FromHardwareId(id, out mouse)) { - RemoveMouse(sender, device); + RemoveMouse(sender, id); recognized = true; } - if (KeyboardDevices.ContainsKey(device)) + if (KeyboardDevices.FromHardwareId(id, out keyboard)) { - RemoveKeyboard(sender, device); + RemoveKeyboard(sender, id); recognized = true; } - if (JoystickDevices.ContainsKey(device)) + if (JoystickDevices.FromHardwareId(id, out joystick)) { - RemoveJoystick(sender, device); + RemoveJoystick(sender, id); recognized = true; } @@ -439,15 +454,16 @@ namespace OpenTK.Platform.MacOS MouseData mouse; KeyboardData keyboard; JoystickData joystick; - if (MouseDevices.TryGetValue(context, out mouse)) + long id = context.ToInt64(); + if (MouseDevices.FromHardwareId(id, out mouse)) { UpdateMouse(mouse, val); } - else if (KeyboardDevices.TryGetValue(context, out keyboard)) + else if (KeyboardDevices.FromHardwareId(id, out keyboard)) { UpdateKeyboard(keyboard, val); } - else if (JoystickDevices.TryGetValue(context, out joystick)) + else if (JoystickDevices.FromHardwareId(id, out joystick)) { UpdateJoystick(joystick, val); } @@ -466,24 +482,16 @@ namespace OpenTK.Platform.MacOS void AddMouse(CFAllocatorRef sender, CFAllocatorRef device) { - if (!MouseDevices.ContainsKey(device)) - { - Debug.Print("Mouse device {0:x} discovered, sender is {1:x}", device, sender); - MouseIndexToDevice.Add(MouseDevices.Count, device); - MouseDevices.Add(device, new MouseData()); - } - else - { - Debug.Print("Mouse device {0:x} reconnected, sender is {1:x}", device, sender); - } - MouseDevices[device].State.SetIsConnected(true); + Debug.Print("Mouse device {0:x} discovered, sender is {1:x}", device, sender); + MouseData mouse = new MouseData(device); + mouse.State.SetIsConnected(true); + MouseDevices.Add(device.ToInt64(), mouse); } - void RemoveMouse(CFAllocatorRef sender, CFAllocatorRef device) + void RemoveMouse(CFAllocatorRef sender, long id) { - Debug.Print("Mouse device {0:x} disconnected, sender is {1:x}", device, sender); - // Keep the device in case it comes back later on - MouseDevices[device].State.SetIsConnected(false); + Debug.Print("Mouse device {0:x} disconnected, sender is {1:x}", id, sender); + MouseDevices.Remove(id); } static void UpdateMouse(MouseData mouse, IOHIDValueRef val) @@ -540,24 +548,16 @@ namespace OpenTK.Platform.MacOS void AddKeyboard(CFAllocatorRef sender, CFAllocatorRef device) { - if (!KeyboardDevices.ContainsKey(device)) - { - Debug.Print("Keyboard device {0:x} discovered, sender is {1:x}", device, sender); - KeyboardIndexToDevice.Add(KeyboardDevices.Count, device); - KeyboardDevices.Add(device, new KeyboardData()); - } - else - { - Debug.Print("Keyboard device {0:x} reconnected, sender is {1:x}", device, sender); - } - KeyboardDevices[device].State.SetIsConnected(true); + Debug.Print("Keyboard device {0:x} discovered, sender is {1:x}", device, sender); + KeyboardData keyboard = new KeyboardData(device); + keyboard.State.SetIsConnected(true); + KeyboardDevices.Add(device.ToInt64(), keyboard); } - void RemoveKeyboard(CFAllocatorRef sender, CFAllocatorRef device) + void RemoveKeyboard(CFAllocatorRef sender, long id) { - Debug.Print("Keyboard device {0:x} disconnected, sender is {1:x}", device, sender); - // Keep the device in case it comes back later on - KeyboardDevices[device].State.SetIsConnected(false); + Debug.Print("Keyboard device {0:x} disconnected, sender is {1:x}", id, sender); + KeyboardDevices.Remove(id); } static void UpdateKeyboard(KeyboardData keyboard, IOHIDValueRef val) @@ -651,7 +651,7 @@ namespace OpenTK.Platform.MacOS CFArrayRef element_array_ref = NativeMethods.IOHIDDeviceCopyMatchingElements(device, IntPtr.Zero, IntPtr.Zero); if (element_array_ref != IntPtr.Zero) { - joy = new JoystickData(); + joy = new JoystickData(device); CFStringRef name_ref = NativeMethods.IOHIDDeviceGetProperty(device, NativeMethods.IOHIDProductKey); string name = CF.CFStringGetCString(name_ref); @@ -823,16 +823,7 @@ namespace OpenTK.Platform.MacOS JoystickData GetJoystick(int index) { - IntPtr device; - if (JoystickIndexToDevice.TryGetValue(index, out device)) - { - JoystickData joystick; - if (JoystickDevices.TryGetValue(device, out joystick)) - { - return joystick; - } - } - return null; + return JoystickDevices.FromIndex(index); } void AddJoystick(CFAllocatorRef sender, CFAllocatorRef device) @@ -845,42 +836,7 @@ namespace OpenTK.Platform.MacOS JoystickData joy = CreateJoystick(sender, device); if (joy != null) { - // Add a device->joy lookup entry for this device. - if (!JoystickDevices.ContainsKey(device)) - { - // First time we've seen this device. - JoystickDevices.Add(device, joy); - } - else - { - // This is an old device that is replugged. - // This branch does not appear to be executed, ever. - JoystickDevices[device] = joy; - } - - // Add an index->device lookup entry for this device. - // Use the first free (i.e. disconnected) index. - // If all indices are connected, append a new one. - int i; - for (i = 0; i < JoystickIndexToDevice.Count; i++) - { - IntPtr candidate = JoystickIndexToDevice[i]; - if (!JoystickDevices[candidate].State.IsConnected) - { - break; - } - } - - if (i == JoystickDevices.Count) - { - // All indices connected, append a new one. - JoystickIndexToDevice.Add(JoystickDevices.Count, device); - } - else - { - // Replace joystick at that index - JoystickIndexToDevice[i] = device; - } + JoystickDevices.Add(device.ToInt64(), joy); } } finally @@ -889,12 +845,10 @@ namespace OpenTK.Platform.MacOS } } - void RemoveJoystick(CFAllocatorRef sender, CFAllocatorRef device) + void RemoveJoystick(CFAllocatorRef sender, long id) { - Debug.Print("Joystick device {0:x} disconnected, sender is {1:x}", device, sender); - // Keep the device in case it comes back later on - JoystickDevices[device].State = new JoystickState(); - JoystickDevices[device].Capabilities = new JoystickCapabilities(); + Debug.Print("Joystick device {0:x} disconnected, sender is {1:x}", id, sender); + JoystickDevices.Remove(id); } static void UpdateJoystick(JoystickData joy, IOHIDValueRef val) @@ -1064,9 +1018,9 @@ namespace OpenTK.Platform.MacOS MouseState IMouseDriver2.GetState() { MouseState master = new MouseState(); - foreach (KeyValuePair item in MouseDevices) + foreach (MouseData item in MouseDevices) { - master.MergeBits(item.Value.State); + master.MergeBits(item.State); } return master; @@ -1074,10 +1028,10 @@ namespace OpenTK.Platform.MacOS MouseState IMouseDriver2.GetState(int index) { - IntPtr device; - if (MouseIndexToDevice.TryGetValue(index, out device)) + MouseData mouse; + if (MouseDevices.FromIndex(index, out mouse)) { - return MouseDevices[device].State; + return mouse.State; } return new MouseState(); @@ -1101,9 +1055,9 @@ namespace OpenTK.Platform.MacOS KeyboardState IKeyboardDriver2.GetState() { KeyboardState master = new KeyboardState(); - foreach (KeyValuePair item in KeyboardDevices) + foreach (KeyboardData item in KeyboardDevices) { - master.MergeBits(item.Value.State); + master.MergeBits(item.State); } return master; @@ -1111,10 +1065,10 @@ namespace OpenTK.Platform.MacOS KeyboardState IKeyboardDriver2.GetState(int index) { - IntPtr device; - if (KeyboardIndexToDevice.TryGetValue(index, out device)) + KeyboardData keyboard; + if (KeyboardDevices.FromIndex(index, out keyboard)) { - return KeyboardDevices[device].State; + return keyboard.State; } return new KeyboardState(); @@ -1122,11 +1076,11 @@ namespace OpenTK.Platform.MacOS string IKeyboardDriver2.GetDeviceName(int index) { - IntPtr device; - if (KeyboardIndexToDevice.TryGetValue(index, out device)) + KeyboardData keyboard; + if (KeyboardDevices.FromIndex(index, out keyboard)) { - IntPtr vendor_id = NativeMethods.IOHIDDeviceGetProperty(device, NativeMethods.IOHIDVendorIDKey); - IntPtr product_id = NativeMethods.IOHIDDeviceGetProperty(device, NativeMethods.IOHIDProductIDKey); + IntPtr vendor_id = NativeMethods.IOHIDDeviceGetProperty(keyboard.Id, NativeMethods.IOHIDVendorIDKey); + IntPtr product_id = NativeMethods.IOHIDDeviceGetProperty(keyboard.Id, NativeMethods.IOHIDProductIDKey); // Todo: find out the real vendor/product name from the relevant ids. return String.Format("{0}:{1}", vendor_id, product_id); } @@ -1750,19 +1704,19 @@ namespace OpenTK.Platform.MacOS NativeMethods.IOHIDManagerUnscheduleFromRunLoop( hidmanager, RunLoop, InputLoopMode); - foreach (var device in MouseDevices.Keys) + foreach (var device in MouseDevices) { - DeviceRemoved(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, device); + DeviceRemoved(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, device.Id); } - foreach (var device in KeyboardDevices.Keys) + foreach (var device in KeyboardDevices) { - DeviceRemoved(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, device); + DeviceRemoved(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, device.Id); } - foreach (var device in JoystickDevices.Keys) + foreach (var device in JoystickDevices) { - DeviceRemoved(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, device); + DeviceRemoved(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, device.Id); } if (hidmanager != IntPtr.Zero)