void DeviceValueReceived(IntPtr context, IOReturn res, IntPtr sender, IOHIDValueRef val) { if (disposed) { Debug.Print("DeviceValueReceived({0}, {1}, {2}, {3}) called on disposed {4}", context, res, sender, val, GetType()); return; } MouseState mouse; KeyboardState keyboard; if (MouseDevices.TryGetValue(context, out mouse)) { MouseDevices[context] = UpdateMouse(mouse, val); } else if (KeyboardDevices.TryGetValue(context, out keyboard)) { KeyboardDevices[context] = UpdateKeyboard(keyboard, val); } else { //Debug.Print ("Device {0:x} not found in list of keyboards or mice", sender); } }
static KeyboardState UpdateKeyboard(KeyboardState state, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); // This will supress the debug printing below. Seems like it generates a lot of -1s. // Couldn't find any details in USB spec or Apple docs for this behavior. if (usage < 0) { return(state); } switch (page) { case HIDPage.GenericDesktop: case HIDPage.KeyboardOrKeypad: if (usage >= RawKeyMap.Length) { Debug.Print("[Warning] Key {0} not mapped.", usage); return(state); } state.SetKeyState(RawKeyMap[usage], (byte)usage, v_int != 0); break; } return(state); }
static MouseState UpdateMouse(MouseState state, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); //double v_physical = NativeMethods.IOHIDValueGetScaledValue(val, IOHIDValueScaleType.Physical); //double v_calbrated = NativeMethods.IOHIDValueGetScaledValue(val, IOHIDValueScaleType.Calibrated); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); switch (page) { case HIDPage.GenericDesktop: switch ((HIDUsageGD)usage) { case HIDUsageGD.X: state.X += v_int; break; case HIDUsageGD.Y: state.Y += v_int; break; case HIDUsageGD.Wheel: state.WheelPrecise += v_int; break; } break; case HIDPage.Button: state[OpenTK.Input.MouseButton.Left + usage - 1] = v_int == 1; break; } return(state); }
void DeviceValueReceived(IntPtr context, IOReturn res, IntPtr sender, IOHIDValueRef val) { MouseState mouse; KeyboardState keyboard; if (MouseDevices.TryGetValue(sender, out mouse)) { MouseDevices[sender] = UpdateMouse(mouse, val); } else if (KeyboardDevices.TryGetValue(sender, out keyboard)) { KeyboardDevices[sender] = UpdateKeyboard(keyboard, val); } }
static KeyboardState UpdateKeyboard(KeyboardState state, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); switch (page) { case HIDPage.GenericDesktop: case HIDPage.KeyboardOrKeypad: int raw = (int)usage; if (raw >= RawKeyMap.Length || raw < 0) { Debug.Print("[Warning] Key {0} not mapped.", raw); return(state); } Key key = RawKeyMap[raw]; state[key] = v_int != 0; break; } return(state); }
public static extern CFIndex IOHIDValueGetIntegerValue(IOHIDValueRef @value);
public static extern CFIndex IOHIDValueGetLength(IOHIDValueRef value);
public static extern IOHIDElementRef IOHIDValueGetElement(IOHIDValueRef @value);
void DeviceValueReceived(IntPtr context, IOReturn res, IntPtr sender, IOHIDValueRef val) { MouseState mouse; KeyboardState keyboard; if (MouseDevices.TryGetValue(context, out mouse)) { MouseDevices[context] = UpdateMouse(mouse, val); } else if (KeyboardDevices.TryGetValue(context, out keyboard)) { KeyboardDevices[context] = UpdateKeyboard(keyboard, val); }else{ //Debug.Print ("Device {0:x} not found in list of keyboards or mice", sender); } }
static MouseState UpdateMouse(MouseState state, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); //double v_physical = NativeMethods.IOHIDValueGetScaledValue(val, IOHIDValueScaleType.Physical); //double v_calbrated = NativeMethods.IOHIDValueGetScaledValue(val, IOHIDValueScaleType.Calibrated); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); switch (page) { case HIDPage.GenericDesktop: switch ((HIDUsageGD)usage) { case HIDUsageGD.X: state.X += v_int; break; case HIDUsageGD.Y: state.Y += v_int; break; case HIDUsageGD.Wheel: state.WheelPrecise += v_int; break; } break; case HIDPage.Button: state[OpenTK.Input.MouseButton.Left + usage - 1] = v_int == 1; break; } return state; }
static bool GetJoystickButton(IOHIDValueRef val, IOHIDElementRef element) { // Todo: analogue buttons are transformed to digital int value = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); return value >= 1; }
static void UpdateMouse(MouseData mouse, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); //double v_physical = NativeMethods.IOHIDValueGetScaledValue(val, IOHIDValueScaleType.Physical); //double v_calbrated = NativeMethods.IOHIDValueGetScaledValue(val, IOHIDValueScaleType.Calibrated); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); switch (page) { case HIDPage.GenericDesktop: switch ((HIDUsageGD)usage) { case HIDUsageGD.X: mouse.State.X += v_int; break; case HIDUsageGD.Y: mouse.State.Y += v_int; break; case HIDUsageGD.Wheel: mouse.State.SetScrollRelative(0, v_int); break; } break; case HIDPage.Button: mouse.State[OpenTK.Input.MouseButton.Left + usage - 1] = v_int == 1; break; case HIDPage.Consumer: switch ((HIDUsageCD)usage) { case HIDUsageCD.ACPan: mouse.State.SetScrollRelative(v_int, 0); break; } break; } }
static void UpdateJoystick(JoystickData joy, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); switch (page) { case HIDPage.GenericDesktop: switch ((HIDUsageGD)usage) { case HIDUsageGD.X: case HIDUsageGD.Y: case HIDUsageGD.Z: case HIDUsageGD.Rx: case HIDUsageGD.Ry: case HIDUsageGD.Rz: case HIDUsageGD.Slider: case HIDUsageGD.Dial: case HIDUsageGD.Wheel: short offset = GetJoystickAxis(val, elem); JoystickAxis axis = TranslateJoystickAxis(usage); if (axis >= JoystickAxis.Axis0 && axis <= JoystickAxis.Last) { joy.State.SetAxis(axis, offset); } break; case HIDUsageGD.Hatswitch: HatPosition position = GetJoystickHat(val, elem); JoystickHat hat = TranslateJoystickHat(joy, elem); if (hat >= JoystickHat.Hat0 && hat <= JoystickHat.Last) { joy.State.SetHat(hat, new JoystickHatState(position)); } break; } break; case HIDPage.Simulation: switch ((HIDUsageSim)usage) { case HIDUsageSim.Rudder: case HIDUsageSim.Throttle: short offset = GetJoystickAxis(val, elem); JoystickAxis axis = TranslateJoystickAxis(usage); if (axis >= JoystickAxis.Axis0 && axis <= JoystickAxis.Last) { joy.State.SetAxis(axis, offset); } break; } break; case HIDPage.Button: { bool pressed = GetJoystickButton(val, elem); JoystickButton button = TranslateJoystickButton(joy, usage); if (button >= JoystickButton.Button0 && button <= JoystickButton.Last) { joy.State.SetButton(button, pressed); } } break; } }
public static extern double IOHIDValueGetScaledValue( IOHIDValueRef @value, IOHIDValueScaleType type) ;
static KeyboardState UpdateKeyboard(KeyboardState state, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); switch (page) { case HIDPage.GenericDesktop: case HIDPage.KeyboardOrKeypad: int raw = (int)usage; if (raw >= RawKeyMap.Length || raw < 0) { Debug.Print("[Warning] Key {0} not mapped.", raw); return state; } Key key = RawKeyMap[raw]; state[key] = v_int != 0; break; } return state; }
/// <summary> /// Handler of callback by OS planned to be used with default OSXDriver /// </summary> /// <param name="context">Context.</param> /// <param name="res">Res.</param> /// <param name="sender">Sender.</param> /// <param name="valRef">Value reference.</param> internal void DeviceValueReceived(IntPtr context, IOReturn res, IntPtr sender, IOHIDValueRef valRef) { IOHIDElementRef element = Native.IOHIDValueGetElement(valRef); uint uid = Native.IOHIDElementGetCookie(element); int value; Native.IOHIDElementType type = Native.IOHIDElementGetType(element); GenericHIDDevice device; value = Native.IOHIDValueGetIntegerValue(valRef); //UnityEngine.Debug.Log ("DeviceValueReceived:"+value); try{ GCHandle gch = GCHandle.FromIntPtr(context); device = (GenericHIDDevice)gch.Target; } catch (Exception e) { UnityEngine.Debug.LogException(e); return; } byte[] typeBuff = BitConverter.GetBytes((uint)type); byte[] uidBuff = BitConverter.GetBytes(uid); byte[] valueBuff = BitConverter.GetBytes(value); byte[] result = new byte[typeBuff.Length + uidBuff.Length + valueBuff.Length]; System.Buffer.BlockCopy(typeBuff, 0, result, 0, typeBuff.Length); System.Buffer.BlockCopy(uidBuff, 0, result, typeBuff.Length, uidBuff.Length); System.Buffer.BlockCopy(valueBuff, 0, result, typeBuff.Length + uidBuff.Length, valueBuff.Length); device.__lastHIDReport.Status = HIDReport.ReadStatus.Success; device.__lastHIDReport.Data = result; }
static KeyboardState UpdateKeyboard(KeyboardState state, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); // This will supress the debug printing below. Seems like it generates a lot of -1s. // Couldn't find any details in USB spec or Apple docs for this behavior. if(usage < 0 ) return state; switch (page) { case HIDPage.GenericDesktop: case HIDPage.KeyboardOrKeypad: int raw = (int) usage; if (raw >= RawKeyMap.Length) { Debug.Print("[Warning] Key {0} not mapped.", raw); return state; } Key key = RawKeyMap[raw]; state[key] = v_int != 0; break; } return state; }
void DeviceValueReceived(IntPtr context, IOReturn res, IntPtr sender, IOHIDValueRef val) { try { if (disposed) { Debug.Print("DeviceValueReceived({0}, {1}, {2}, {3}) called on disposed {4}", context, res, sender, val, GetType()); return; } MouseData mouse; KeyboardData keyboard; JoystickData joystick; if (MouseDevices.TryGetValue(context, out mouse)) { UpdateMouse(mouse, val); } else if (KeyboardDevices.TryGetValue(context, out keyboard)) { UpdateKeyboard(keyboard, val); } else if (JoystickDevices.TryGetValue(context, out joystick)) { UpdateJoystick(joystick, val); } else { //Debug.Print ("Device {0:x} not found in list of keyboards or mice", sender); } } catch (Exception e) { Debug.Print("[Mac] Exception in managed callback: {0}", e); } }
static void UpdateKeyboard(KeyboardData keyboard, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); // This will supress the debug printing below. Seems like it generates a lot of -1s. // Couldn't find any details in USB spec or Apple docs for this behavior. if (usage >= 0) { switch (page) { case HIDPage.GenericDesktop: case HIDPage.KeyboardOrKeypad: if (usage >= RawKeyMap.Length) { Debug.Print("[Warning] Key {0} not mapped.", usage); } keyboard.State[RawKeyMap[usage]] = v_int != 0; break; } } }
static short GetJoystickAxis(IOHIDValueRef val, IOHIDElementRef element) { int max = NativeMethods.IOHIDElementGetLogicalMax(element).ToInt32(); int min = NativeMethods.IOHIDElementGetLogicalMin(element).ToInt32(); int offset = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); if (offset < min) offset = min; if (offset > max) offset = max; const int range = short.MaxValue - short.MinValue + 1; const int half_range = short.MaxValue + 1; return (short)((offset - min) * range / (max - min) + half_range); }
public static extern double IOHIDValueGetScaledValue( IOHIDValueRef @value, IOHIDValueScaleType type);
static HatPosition GetJoystickHat(IOHIDValueRef val, IOHIDElementRef element) { HatPosition position = HatPosition.Centered; int max = NativeMethods.IOHIDElementGetLogicalMax(element).ToInt32(); int min = NativeMethods.IOHIDElementGetLogicalMin(element).ToInt32(); int value = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32() - min; int range = Math.Abs(max - min + 1); if (value >= 0) { if (range == 4) { // 4-position hat (no diagonals) // 0 = up; 1 = right; 2 = down; 3 = left // map to a 8-position hat (processed below) value *= 2; } if (range == 8) { // 0 = up; 1 = up-right; 2 = right; 3 = right-down; // 4 = down; 5 = down-left; 6 = left; 7 = up-left // Our HatPosition enum position = (HatPosition)value; } else { // Todo: implement support for continuous hats } } return position; }
void DeviceValueReceived(IntPtr context, IOReturn res, IntPtr sender, IOHIDValueRef val) { if (disposed) { Debug.Print("DeviceValueReceived({0}, {1}, {2}, {3}) called on disposed {4}", context, res, sender, val, GetType()); return; } MouseState mouse; KeyboardState keyboard; if (MouseDevices.TryGetValue(context, out mouse)) { MouseDevices[context] = UpdateMouse(mouse, val); } else if (KeyboardDevices.TryGetValue(context, out keyboard)) { KeyboardDevices[context] = UpdateKeyboard(keyboard, val); }else{ //Debug.Print ("Device {0:x} not found in list of keyboards or mice", sender); } }