context: /******************************************************************************\
  * Copyright (C) 2012-2016 Leap Motion, Inc. All rights reserved.               *
  * Leap Motion proprietary and confidential. Not for distribution.              *
  * Use subject to the terms of the Leap Motion SDK Agreement available at       *
  * https://developer.leapmotion.com/sdk_agreement, or another agreement         *
  * between Leap Motion and you, your company or other organization.             *
  \******************************************************************************/
  
  
  namespace LeapInternal
  {
    using System;
    using System.Runtime.InteropServices;
  
  
    public enum eLeapConnectionStatus : uint
    {
      eLeapConnectionStatus_NotConnected = 0, //!< // A connection has been established
      eLeapConnectionStatus_Connected, //!< The connection has not been completed. Call OpenConnection.
      eLeapConnectionStatus_HandshakeIncomplete, //!< The connection handshake has not completed
      eLeapConnectionStatus_NotRunning = 0xE7030004 //!< A connection could not be established because the server does not appear to be running
    };
  
    public enum eLeapDeviceCaps : uint
    {
      eLeapDeviceCaps_Color = 0x00000001, //!< The device can send color images
      eLeapDeviceCaps_Embedded = 0x00010000 //!< The device is embedded in another piece of hardware, such as a keyboard or laptop
    };
  
    public enum eLeapDeviceType : uint
    {
      eLeapDeviceType_Peripheral = 0x0003, //!< The Leap Motion consumer peripheral
      eLeapDeviceType_Legacy = 0x1001, //!< HOPS/PONGO Legacy device
      eLeapDeviceType_Hops = 0x1002, //!< Leap Motion HOPS Keyboard
      eLeapDeviceType_Pongo = 0x1003, //!< Leap Motion Pongo laptop-embedded device
      eLeapDeviceType_Dragonfly = 0x1102, //!< Internal research product codename "Dragonfly"
      eLeapDeviceType_Nightcrawler = 0x1201 //!< Internal research product codename "Nightcrawler"
    };
  
    public enum eDistortionMatrixType
    {
      eDistortionMatrixType_64x64 //!< A 64x64 matrix of pairs of points.
    };
  
    public enum eLeapPolicyFlag : uint
    {
      eLeapPolicyFlag_BackgroundFrames = 0x00000001, //!< Allows frame receipt even when this application is not the foreground application
      eLeapPolicyFlag_OptimizeHMD = 0x00000004, //!< Optimize HMD Policy Flag
      eLeapPolicyFlag_AllowPauseResume = 0x00000008, //!< Modifies the security token to allow calls to LeapPauseDevice to succeed
      eLeapPolicyFlag_IncludeAllFrames = 0x00008000, //!< Include native-app frames when receiving background frames.
      eLeapPolicyFlag_NonExclusive = 0x00800000  //!< Allow background apps to also receive frames.
    };
  
  
    public enum eLeapDeviceStatus : uint
    {
      eLeapDeviceStatus_Streaming = 0x00000001, //!< Presently sending frames to all clients that have requested them
      eLeapDeviceStatus_Paused = 0x00000002, //!< Device streaming has been paused
      eLeapDeviceStatus_UnknownFailure = 0xE8010000, //!< The device has failed, but the failure reason is not known
      eLeapDeviceStatus_BadCalibration = 0xE8010001, //!< Bad calibration, cannot send frames
      eLeapDeviceStatus_BadFirmware = 0xE8010002, //!< Corrupt firmware and/or cannot receive a required firmware update
      eLeapDeviceStatus_BadTransport = 0xE8010003, //!< Exhibiting USB communications issues
      eLeapDeviceStatus_BadControl = 0xE8010004, //!< Missing critical control interfaces needed for communication
    };
  
    public enum eLeapImageType
    {
      eLeapImageType_Unknown = 0,
      eLeapImageType_Default, //!< Default processed IR image
      eLeapImageType_Raw //!< Image from raw sensor values
    };
  
    public enum eLeapImageFormat : uint
    {
      eLeapImageFormat_UNKNOWN = 0, //!< Unknown format (shouldn't happen)
      eLeapImageType_IR = 0x317249, //!< An infrared image
      eLeapImageType_RGBIr_Bayer = 0x49425247, //!< A Bayer RGBIr image with uncorrected RGB channels
    };
  
    public enum eLeapPerspectiveType
    {
      eLeapPerspectiveType_invalid = 0, //!< Reserved, invalid
      eLeapPerspectiveType_stereo_left = 1, //!< A canonically left image
      eLeapPerspectiveType_stereo_right = 2, //!< A canonically right image
      eLeapPerspectiveType_mono = 3, //!< Reserved for future use
    };
  
    public enum eLeapImageRequestError
    {
      eLeapImageRequestError_Unknown, //!< The reason for the failure is unknown
      eLeapImageRequestError_ImagesDisabled, //!< Images are turned off in the user's configuration
      eLeapImageRequestError_Unavailable, //!< The requested images are not available
      eLeapImageRequestError_InsufficientBuffer, //!< The provided buffer is not large enough for the requested images
    }
  
    public enum eLeapHandType
    {
      eLeapHandType_Left, //!< Left hand
      eLeapHandType_Right //!< Right hand
    };
  
    public enum eLeapLogSeverity
    {
      eLeapLogSeverity_Unknown = 0,
      eLeapLogSeverity_Critical,
      eLeapLogSeverity_Warning,
      eLeapLogSeverity_Information
    };
  
    public enum eLeapValueType : int
    {
      eLeapValueType_Unknown,
      eLeapValueType_Boolean,
      eLeapValueType_Int32,
      eleapValueType_Float,
      eLeapValueType_String
    };
  
    public enum eLeapRS : uint
    {
      eLeapRS_Success = 0x00000000, //!< The operation completed successfully
      eLeapRS_UnknownError = 0xE2010000, //!< An unknown error has occurred
      eLeapRS_InvalidArgument = 0xE2010001, //!< An invalid argument was specified
      eLeapRS_InsufficientResources = 0xE2010002, //!< Insufficient resources existed to complete the request
      eLeapRS_InsufficientBuffer = 0xE2010003, //!< The specified buffer was not large enough to complete the request
      eLeapRS_Timeout = 0xE2010004, //!< The requested operation has timed out
      eLeapRS_NotConnected = 0xE2010005, //!< The connection is not open
      eLeapRS_HandshakeIncomplete = 0xE2010006, //!< The request did not succeed because the client has not finished connecting to the server
      eLeapRS_BufferSizeOverflow = 0xE2010007, //!< The specified buffer size is too large
      eLeapRS_ProtocolError = 0xE2010008, //!< A communications protocol error has occurred
      eLeapRS_InvalidClientID = 0xE2010009, //!< The server incorrectly specified zero as a client ID
      eLeapRS_UnexpectedClosed = 0xE201000A, //!< The connection to the service was unexpectedly closed while reading a message
      eLeapRS_CannotCancelImageFrameRequest = 0xE201000B, //!< An attempt to cancel an image request failed (either too late, or the image token was invalid)
      eLeapRS_NotAvailable = 0xE7010002, //!< A connection could not be established to the Leap Motion service
      eLeapRS_NotStreaming = 0xE7010004, //!< The requested operation can only be performed while the device is streaming
                                         /**
                                         * It is possible that the device identifier
                                         * is invalid, or that the device has been disconnected since being enumerated.
                                         */
      eLeapRS_CannotOpenDevice = 0xE7010005, //!< The specified device could not be opened. Invalid device identifier or the device has been disconnected since being enumerated.
    };
  
    public enum eLeapEventType
    {
      eLeapEventType_None = 0, //!< No event occurred in the specified timeout period
      eLeapEventType_Connection, //!< A connection event has occurred
      eLeapEventType_ConnectionLost, //!< The connection with the service has been lost
      eLeapEventType_Device, //!<  A device event has occurred
      eLeapEventType_DeviceFailure, //!< A device failure event has occurred
      eLeapEventType_PolicyChange, //!< A change in policy occurred
      eLeapEventType_Tracking = 0x100, //!< A tracking frame has been received
                                       /**
                                        * The user must invoke LeapReceiveImage(evt->Image, ...) if image data is desired.  If this call
                                        * is not made, the image will be discarded from the stream.
                                        *
                                        * Depending on the image types the user has requested, this event may be asserted more than once
                                        * per frame.
                                        */
      eLeapEventType_ImageRequestError, //!< A requested image could not be acquired
      eLeapEventType_ImageComplete, //!<  An image transfer is complete
      eLeapEventType_LogEvent, //!< A diagnostic event has occured
  
      /**
       * The eLeapEventType_DeviceLost event type will always be asserted regardless of the user flags assignment.
       * Users are required to correctly handle this event when it is received.
       *
       * This event is generally asserted when the device has been detached from the system, when the
       * connection to the service has been lost, or if the device is closed while streaming.  Generally,
       * any event where the system can conclude no further frames will be received will cause this
       * method to be invoked.
       */
      eLeapEventType_DeviceLost, //!< Event asserted when the underlying device object has been lost
      eLeapEventType_ConfigResponse, //!< Response to a Config value request
      eLeapEventType_ConfigChange //!< Success response to a Config value change
    };
  
    public enum eLeapDeviceFlag : uint
    {
      /**
      * This flag is updated when the user pauses or resumes tracking on the device from the Leap control
      * panel.  Modification of this flag will fail if the AllowPauseResume policy is not set on this device
      * object.
      */
      eLeapDeviceFlag_Stream = 0x00000001 //!< Flag set if the device is presently streaming frames
    };
    public enum eLeapConnectionFlags : uint
    {
      eLeapConnectionFlags_Default = 0x00000000, //!< Currently there is only a default state flag.
    };
  
  
    //Note the following LeapC structs are just IntPtrs in C#:
    // LEAP_CONNECTION is an IntPtr
    // LEAP_DEVICE is an IntPtr
    // LEAP_CLOCK_REBASER is an IntPtr
  
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
    public struct LEAP_CONNECTION_CONFIG
    {
      public UInt32 size;
      public UInt32 flags;
      public string server_namespace;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_CONNECTION_INFO
    {
      public UInt32 size;
      public eLeapConnectionStatus status;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_CONNECTION_EVENT
    {
      public UInt32 flags;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_DEVICE_REF
    {
      public IntPtr handle; //void *
      public UInt32 id;
      public LEAP_DEVICE_REF(IntPtr handle, UInt32 id)
      {
        this.handle = handle;
        this.id = id;
      }
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_CONNECTION_LOST_EVENT
    {
      public UInt32 flags;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_DEVICE_EVENT
    {
      public UInt32 flags;
      public LEAP_DEVICE_REF device;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_DEVICE_FAILURE_EVENT
    {
      public eLeapDeviceStatus status;
      public IntPtr hDevice;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_TRACKING_EVENT
    {
      public LEAP_FRAME_HEADER info;
      public Int64 tracking_id;
      public LEAP_VECTOR interaction_box_size;
      public LEAP_VECTOR interaction_box_center;
      public UInt32 nHands;
      public IntPtr pHands; //LEAP_HAND*
      public float framerate;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_CONNECTION_MESSAGE
    {
      public UInt32 size;
      public eLeapEventType type;
      public IntPtr eventStructPtr;
    }
  
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_DISCONNECTION_EVENT
    {
      public UInt32 reserved;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
    public struct LEAP_DEVICE_INFO
    {
      public UInt32 size;
      public UInt32 status;
      public UInt32 caps;
      public eLeapDeviceType type;
      public UInt32 baseline;
      public UInt32 serial_length;
      public IntPtr serial; //char*
      public float h_fov;
      public float v_fov;
      public UInt32 range;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_DISTORTION_MATRIX
    {
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 64 * 64 * 2)]//2floats * 64 width * 64 height * 2 matrices
      public float[] matrix_data;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_FRAME_HEADER
    {
      public IntPtr reserved;
      public Int64 frame_id;
      public Int64 timestamp;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_IMAGE_FRAME_REQUEST_TOKEN
    {
      public UInt32 requestID;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_IMAGE_COMPLETE_EVENT
    {
      public LEAP_IMAGE_FRAME_REQUEST_TOKEN token;
      public LEAP_FRAME_HEADER info;
      public IntPtr properties; //LEAP_IMAGE_PROPERTIES*
      public UInt64 matrix_version;
      public IntPtr calib; //LEAP_CALIBRATION
      public IntPtr distortionMatrix; //LEAP_DISTORTION_MATRIX* distortion_matrix[2]
      public IntPtr pfnData; // void* the user-supplied buffer
      public UInt64 data_written; //The amount of data written to the buffer
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_IMAGE_FRAME_DESCRIPTION
    {
      public Int64 frame_id;
      public eLeapImageType type;
      public UInt64 buffer_len;
      public IntPtr pBuffer;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_IMAGE_FRAME_REQUEST_ERROR_EVENT
    {
      public LEAP_IMAGE_FRAME_REQUEST_TOKEN token;
      public eLeapImageRequestError error;
      public UInt64 required_buffer_len; //The required buffer size, for insufficient buffer errors
      public LEAP_IMAGE_FRAME_DESCRIPTION description;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_IMAGE_PROPERTIES
    {
      public eLeapImageType type;
      public eLeapImageFormat format;
      public UInt32 bpp;
      public UInt32 width;
      public UInt32 height;
      public float x_scale;
      public float y_scale;
      public float x_offset;
      public float y_offset;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_VECTOR
    {
      public float x;
      public float y;
      public float z;
  
      public Leap.Vector ToLeapVector()
      {
        return new Leap.Vector(x, y, z);
      }
      public LEAP_VECTOR(Leap.Vector leap)
      {
        x = leap.x;
        y = leap.y;
        z = leap.z;
      }
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_MATRIX
    {
      public LEAP_VECTOR x_basis;
      public LEAP_VECTOR y_basis;
      public LEAP_VECTOR z_basis;
  
      public Leap.Matrix ToLeapMatrix()
      {
        return new Leap.Matrix(x_basis.ToLeapVector(),
                               y_basis.ToLeapVector(),
                               z_basis.ToLeapVector());
      }
  
      public LEAP_MATRIX(Leap.Matrix leap)
      {
        x_basis = new LEAP_VECTOR(leap.xBasis);
        y_basis = new LEAP_VECTOR(leap.yBasis);
        z_basis = new LEAP_VECTOR(leap.zBasis);
      }
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_BONE
    {
      public LEAP_VECTOR prev_joint;
      public LEAP_VECTOR next_joint;
      public float width;
      public LEAP_MATRIX basis;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_DIGIT
    {
      public Int32 finger_id;
      public LEAP_BONE metacarpal;
      public LEAP_BONE proximal;
      public LEAP_BONE intermediate;
      public LEAP_BONE distal;
      public LEAP_VECTOR tip_velocity;
      public LEAP_VECTOR stabilized_tip_position;
      public Int32 is_extended;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_PALM
    {
      public LEAP_VECTOR position;
      public LEAP_VECTOR stabilized_position;
      public LEAP_VECTOR velocity;
      public LEAP_VECTOR normal;
      public float width;
      public LEAP_VECTOR direction;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_HAND
    {
      public UInt32 id;
      public UInt32 flags;
      public eLeapHandType type;
      public float confidence;
      public UInt64 visible_time;
      public float pinch_distance;
      public float grab_angle;
      public float pinch_strength;
      public float grab_strength;
      public LEAP_PALM palm;
      public LEAP_DIGIT thumb;
      public LEAP_DIGIT index;
      public LEAP_DIGIT middle;
      public LEAP_DIGIT ring;
      public LEAP_DIGIT pinky;
      public LEAP_BONE arm;
    }
  
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_TIP
    {
      public LEAP_VECTOR position;
      public float radius;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
    public struct LEAP_LOG_EVENT
    {
      public eLeapLogSeverity severity;
      public Int64 timestamp;
      public string message;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
    public struct LEAP_POLICY_EVENT
    {
      public UInt32 reserved;
      public UInt32 current_policy;
    }
  
    [StructLayout(LayoutKind.Explicit, Pack = 1)]
    public struct LEAP_VARIANT_VALUE_TYPE
    {
      [FieldOffset(0)]
      public eLeapValueType type;
      [FieldOffset(4)]
      public Int32 boolValue;
      [FieldOffset(4)]
      public Int32 intValue;
      [FieldOffset(4)]
      public float floatValue;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
    public struct LEAP_VARIANT_REF_TYPE
    {
      public eLeapValueType type;
      public string stringValue;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_CONFIG_RESPONSE_EVENT
    {
      public UInt32 requestId;
      public LEAP_VARIANT_VALUE_TYPE value;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
    public struct LEAP_CONFIG_RESPONSE_EVENT_WITH_REF_TYPE
    {
      public UInt32 requestId;
      public LEAP_VARIANT_REF_TYPE value;
    }
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct LEAP_CONFIG_CHANGE_EVENT
    {
      public UInt32 requestId;
      public Int32 status;
    }
  
    public class LeapC
    {
      private LeapC() { }
      public static int DistortionSize = 64;
  
      [DllImport("LeapC", EntryPoint = "LeapGetNow")]
      public static extern long GetNow();
  
      [DllImport("LeapC", EntryPoint = "LeapCreateClockRebaser")]
      public static extern eLeapRS CreateClockRebaser(out IntPtr phClockRebaser);
  
      [DllImport("LeapC", EntryPoint = "LeapDestroyClockRebaser")]
      public static extern eLeapRS DestroyClockRebaser(IntPtr hClockRebaser);
  
      [DllImport("LeapC", EntryPoint = "LeapUpdateLatency")]
      public static extern eLeapRS UpdateLatency(IntPtr hClockRebaser, Int64 userClock, Int64 leapClock);
  
      [DllImport("LeapC", EntryPoint = "LeapUpdateRebase")]
      public static extern eLeapRS UpdateRebase(IntPtr hClockRebaser, Int64 userClock, Int64 leapClock);
  
      [DllImport("LeapC", EntryPoint = "LeapRebaseClock")]
      public static extern eLeapRS RebaseClock(IntPtr hClockRebaser, Int64 userClock, out Int64 leapClock);
  
      [DllImport("LeapC", EntryPoint = "LeapCreateConnection")]
      public static extern eLeapRS CreateConnection(ref LEAP_CONNECTION_CONFIG pConfig, out IntPtr pConnection);
  
      //Overrides to allow config to be set to null to use default config
      [DllImport("LeapC", EntryPoint = "LeapCreateConnection")]
      private static extern eLeapRS CreateConnection(IntPtr nulled, out IntPtr pConnection);
      public static eLeapRS CreateConnection(out IntPtr pConnection)
      {
        return CreateConnection(IntPtr.Zero, out pConnection);
      }
  
      [DllImport("LeapC", EntryPoint = "LeapGetConnectionInfo")]
      public static extern eLeapRS GetConnectionInfo(IntPtr hConnection, out LEAP_CONNECTION_INFO pInfo);
  
      [DllImport("LeapC", EntryPoint = "LeapOpenConnection")]
      public static extern eLeapRS OpenConnection(IntPtr hConnection);
  
      [DllImport("LeapC", EntryPoint = "LeapGetDeviceList")]
      public static extern eLeapRS GetDeviceList(IntPtr hConnection, [In, Out] LEAP_DEVICE_REF[] pArray, out UInt32 pnArray);
  
      [DllImport("LeapC", EntryPoint = "LeapGetDeviceList")]
      private static extern eLeapRS GetDeviceList(IntPtr hConnection, [In, Out] IntPtr pArray, out UInt32 pnArray);
      //Override to allow pArray argument to be set to null (IntPtr.Zero) in order to get the device count
      public static eLeapRS GetDeviceCount(IntPtr hConnection, out UInt32 deviceCount)
      {
        return GetDeviceList(hConnection, IntPtr.Zero, out deviceCount);
      }
  
      [DllImport("LeapC", EntryPoint = "LeapOpenDevice")]
      public static extern eLeapRS OpenDevice(LEAP_DEVICE_REF rDevice, out IntPtr pDevice);
  
      [DllImport("LeapC", EntryPoint = "LeapGetDeviceInfo", CharSet = CharSet.Ansi)]
      public static extern eLeapRS GetDeviceInfo(IntPtr hDevice, out LEAP_DEVICE_INFO info);
  
      [DllImport("LeapC", EntryPoint = "LeapSetPolicyFlags")]
      public static extern eLeapRS SetPolicyFlags(IntPtr hConnection, UInt64 set, UInt64 clear);
  
      [DllImport("LeapC", EntryPoint = "LeapSetDeviceFlags")]
      public static extern eLeapRS SetDeviceFlags(IntPtr hDevice, UInt64 set, UInt64 clear, out UInt64 prior);
  
      [DllImport("LeapC", EntryPoint = "LeapPollConnection")]
      public static extern eLeapRS PollConnection(IntPtr hConnection, UInt32 timeout, ref LEAP_CONNECTION_MESSAGE msg);
  
      [DllImport("LeapC", EntryPoint = "LeapGetNearestFrames")]
      public static extern eLeapRS GetNearestFrames(IntPtr hConnection, Int64 timestamp, out Int64 lb, out Int64 ub);
  
  
gt:     [DllImport("LeapC", EntryPoint = "LeapGetFrameSize")]