/// <summary>
            /// Retrieves the cursor information contained in the currently duplicated frame, populating the specified desktop frame.
            /// </summary>
            /// <param name="frame"></param>
            /// <param name="frameInfo"></param>
            public void RetrieveCursorMetadata(DesktopFrame frame, OutduplFrameInfo frameInfo)
            {
                // A non-zero mouse update timestamp indicates that there is a mouse position update and optionally a shape change
                if (frameInfo.LastMouseUpdateTime == 0)
                {
                    frame.PointerPosition.Visible = _pointerInfo.Visible;
                    frame.PointerPosition.X       = _pointerInfo.Position.X;
                    frame.PointerPosition.Y       = _pointerInfo.Position.Y;
                    return;
                }

                bool updatePosition = true;

                // Make sure we don't update pointer position wrongly
                // If pointer is invisible, make sure we did not get an update from another output that the last time that said pointer
                // was visible, if so, don't set it to invisible or update.

                if (!frameInfo.PointerPosition.Visible && (_pointerInfo.WhoUpdatedPositionLast != _outputDeviceIndex))
                {
                    updatePosition = false;
                }

                // If two outputs both say they have a visible, only update if new update has newer timestamp
                if (frameInfo.PointerPosition.Visible && _pointerInfo.Visible &&
                    (_pointerInfo.WhoUpdatedPositionLast != _outputDeviceIndex) &&
                    (_pointerInfo.LastTimeStamp > frameInfo.LastMouseUpdateTime))
                {
                    updatePosition = false;
                }

                // Update position
                if (updatePosition)
                {
                    _pointerInfo.Position = new Point(frameInfo.PointerPosition.Position.X, frameInfo.PointerPosition.Position.Y);
                    _pointerInfo.WhoUpdatedPositionLast = _outputDeviceIndex;
                    _pointerInfo.LastTimeStamp          = frameInfo.LastMouseUpdateTime;
                    _pointerInfo.Visible = frameInfo.PointerPosition.Visible;
                }

                frame.PointerPosition.Visible = _pointerInfo.Visible;
                frame.PointerPosition.X       = _pointerInfo.Position.X;
                frame.PointerPosition.Y       = _pointerInfo.Position.Y;

                // No new shape
                if (frameInfo.PointerShapeBufferSize == 0)
                {
                    return;
                }

                if (_pointerInfo.ShapeBuffer == null || frameInfo.PointerShapeBufferSize != _pointerInfo.ShapeBuffer.Length)
                {
                    _pointerInfo.ShapeBuffer = new byte[frameInfo.PointerShapeBufferSize];
                }

                try
                {
                    // Create a new pinned region of memory, copy the contents of the PtrShapeBuffer to it, use it to retrieve the pointer shape and then free the pinned region.
                    unsafe
                    {
                        fixed(byte *ptrShapeBufferPtr = _pointerInfo.ShapeBuffer)
                        {
                            _outputDuplication.GetFramePointerShape(frameInfo.PointerShapeBufferSize, (IntPtr)ptrShapeBufferPtr, out int bufferSize, out _pointerInfo.ShapeInfo);
                        }
                    }
                }
                catch (SharpGenException ex)
                {
                    if (ex.ResultCode.Failure)
                    {
                        throw new DesktopDuplicationException("Failed to get frame pointer shape.");
                    }
                }

                var pointerShapeSpan = new ReadOnlySpan <byte>(_pointerInfo.ShapeBuffer);

                if (!pointerShapeSpan.Trim((byte)0x00).IsEmpty)
                {
                    frame.PointerShape.Width    = _pointerInfo.ShapeInfo.Width;
                    frame.PointerShape.Height   = _pointerInfo.ShapeInfo.Height;
                    frame.PointerShape.Pitch    = _pointerInfo.ShapeInfo.Pitch;
                    frame.PointerShape.Type     = _pointerInfo.ShapeInfo.Type;
                    frame.PointerShape.HotSpotX = _pointerInfo.ShapeInfo.HotSpot.X;
                    frame.PointerShape.HotSpotY = _pointerInfo.ShapeInfo.HotSpot.Y;
                    frame.PointerShapeBuffer    = _pointerInfo.ShapeBuffer;
                }
            }