Exemple #1
0
        /// <summary>
        /// Function to enumerate raw input devices.
        /// </summary>
        /// <returns>An array of raw input device structures.</returns>
        public unsafe static RAWINPUTDEVICELIST[] EnumerateInputDevices()
        {
            int deviceCount = 0;
            int structSize  = DirectAccess.SizeOf <RAWINPUTDEVICELIST>();

            if (GetRawInputDeviceList(IntPtr.Zero, ref deviceCount, structSize) < 0)
            {
                throw new Win32Exception();
            }

            if (deviceCount == 0)
            {
                return(new RAWINPUTDEVICELIST[0]);
            }

            RAWINPUTDEVICELIST *deviceListPtr = stackalloc RAWINPUTDEVICELIST[deviceCount];

            if (GetRawInputDeviceList((IntPtr)deviceListPtr, ref deviceCount, structSize) < 0)
            {
                throw new Win32Exception();
            }

            var result = new RAWINPUTDEVICELIST[deviceCount];

            fixed(RAWINPUTDEVICELIST *resultPtr = &result[0])
            {
                DirectAccess.MemoryCopy(resultPtr, deviceListPtr, structSize * deviceCount);
            }

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Function to retrieve device information.
        /// </summary>
        /// <param name="deviceHandle">Device handle.</param>
        /// <returns>The device information structure.</returns>
        public static unsafe RID_DEVICE_INFO GetDeviceInfo(IntPtr deviceHandle)
        {
            int dataSize = DirectAccess.SizeOf <RID_DEVICE_INFO>();

            byte *data = stackalloc byte[dataSize];

            if (GetRawInputDeviceInfo(deviceHandle, RawInputCommand.DeviceInfo, (IntPtr)data, ref dataSize) < 0)
            {
                throw new Win32Exception();
            }

            RID_DEVICE_INFO result;

            DirectAccess.MemoryCopy(&result, data, dataSize);

            return(result);
        }
Exemple #3
0
        private readonly int _headerSize = DirectAccess.SizeOf <RAWINPUTHEADER>();              // Size of the input data in bytes.
        #endregion

        #region IMessageFilter Members
        /// <summary>
        /// Filters out a message before it is dispatched.
        /// </summary>
        /// <param name="m">The message to be dispatched. You cannot modify this message.</param>
        /// <returns>
        /// true to filter the message and stop it from being dispatched; false to allow the message to continue to the next filter or control.
        /// </returns>
        public unsafe bool PreFilterMessage(ref Message m)
        {
            int dataSize = 0;

            // Get data size.
            int result = Win32API.GetRawInputData(m.LParam, RawInputCommand.Input, IntPtr.Zero, ref dataSize, _headerSize);

            if (result == -1)
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORINP_RAW_CANNOT_READ_DATA);
            }

            // Get actual data.
            var rawInputPtr = stackalloc byte[dataSize];

            result = Win32API.GetRawInputData(m.LParam,
                                              RawInputCommand.Input,
                                              (IntPtr)rawInputPtr,
                                              ref dataSize,
                                              _headerSize);

            if ((result == -1) ||
                (result != dataSize))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORINP_RAW_CANNOT_READ_DATA);
            }

            var rawInput = *((RAWINPUT *)rawInputPtr);

            switch (rawInput.Header.Type)
            {
            case RawInputType.Mouse:
                if (RawInputPointingDeviceData != null)
                {
                    RawInputPointingDeviceData(this,
                                               new RawInputPointingDeviceEventArgs(rawInput.Header.Device,
                                                                                   ref rawInput.Union.Mouse));
                }
                break;

            case RawInputType.Keyboard:
                if (RawInputKeyboardData != null)
                {
                    RawInputKeyboardData(this,
                                         new RawInputKeyboardEventArgs(rawInput.Header.Device,
                                                                       ref rawInput.Union.Keyboard));
                }
                break;

            default:
                if (RawInputHIDData != null)
                {
                    var HIDData    = new byte[rawInput.Union.HID.Size * rawInput.Union.HID.Count];
                    var hidDataPtr = rawInputPtr + _headerSize + 8;

                    fixed(byte *buffer = &HIDData[0])
                    {
                        DirectAccess.MemoryCopy(buffer, hidDataPtr, HIDData.Length);
                    }

                    RawInputHIDData(this,
                                    new RawInputHIDEventArgs(rawInput.Header.Device, ref rawInput.Union.HID, HIDData));
                }
                break;
            }

            return(false);
        }
Exemple #4
0
        /// <summary>
        /// Function to copy (or update in-place) a line with opaque alpha substituion (if required).
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="format">Format of the destination buffer.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is NULL.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>Use this method to copy a single scanline of an image and (optionally) set an opaque constant alpha value.</remarks>
        protected unsafe void CopyScanline(void *src, int srcPitch, void *dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags)
        {
            if (src == null)
            {
                throw new ArgumentNullException("src");
            }

            if (dest == null)
            {
                throw new ArgumentNullException("dest");
            }

            if (format == BufferFormat.Unknown)
            {
                throw new ArgumentException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, BufferFormat.Unknown),
                                            "format");
            }

            int size = (src == dest) ? destPitch : (srcPitch.Min(destPitch));

            if ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha)
            {
                // Do a straight copy.
                switch (format)
                {
                case BufferFormat.R32G32B32A32:
                case BufferFormat.R32G32B32A32_Float:
                case BufferFormat.R32G32B32A32_UInt:
                case BufferFormat.R32G32B32A32_Int:
                {
                    uint alpha = (format == BufferFormat.R32G32B32_Float) ? 0x3F800000
                                                                                                : ((format == BufferFormat.R32G32B32_Int) ? 0x7FFFFFFF : 0xFFFFFFFF);

                    var srcPtr  = (uint *)src;
                    var destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 16)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = *srcPtr;
                            srcPtr += 4;
                        }

                        *destPtr += 3;
                        *(destPtr++) = alpha;
                    }
                }
                    return;

                case BufferFormat.R16G16B16A16:
                case BufferFormat.R16G16B16A16_Float:
                case BufferFormat.R16G16B16A16_UIntNormal:
                case BufferFormat.R16G16B16A16_UInt:
                case BufferFormat.R16G16B16A16_IntNormal:
                case BufferFormat.R16G16B16A16_Int:
                {
                    ushort alpha = 0xFFFF;

                    switch (format)
                    {
                    case BufferFormat.R16G16B16A16_Float:
                        alpha = 0x3C00;
                        break;

                    case BufferFormat.R16G16B16A16_Int:
                    case BufferFormat.R16G16B16A16_IntNormal:
                        alpha = 0x7FFF;
                        break;
                    }

                    var srcPtr  = (ushort *)src;
                    var destPtr = (ushort *)dest;

                    for (int i = 0; i < size; i += 8)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = *srcPtr;
                            srcPtr += 4;
                        }
                        *destPtr += 3;
                        *(destPtr++) = alpha;
                    }
                }
                    return;

                case BufferFormat.R10G10B10A2:
                case BufferFormat.R10G10B10A2_UIntNormal:
                case BufferFormat.R10G10B10A2_UInt:
                case BufferFormat.R10G10B10_XR_BIAS_A2_UIntNormal:
                {
                    var srcPtr  = (uint *)src;
                    var destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 4)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = (*srcPtr) & 0x3FFFFFFF;
                            srcPtr++;
                        }
                        *destPtr |= 0xC0000000;
                        destPtr++;
                    }
                }
                    return;

                case BufferFormat.R8G8B8A8:
                case BufferFormat.R8G8B8A8_UIntNormal:
                case BufferFormat.R8G8B8A8_UIntNormal_sRGB:
                case BufferFormat.R8G8B8A8_UInt:
                case BufferFormat.R8G8B8A8_IntNormal:
                case BufferFormat.R8G8B8A8_Int:
                case BufferFormat.B8G8R8A8_UIntNormal:
                case BufferFormat.B8G8R8A8:
                case BufferFormat.B8G8R8A8_UIntNormal_sRGB:
                {
                    uint alpha = ((format == BufferFormat.R8G8B8A8_Int) || (format == BufferFormat.R8G8B8A8_IntNormal)) ? 0x7F000000 : 0xFF000000;

                    var srcPtr  = (uint *)src;
                    var destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 4)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = (*srcPtr) & 0xFFFFFF;
                            srcPtr++;
                        }
                        *destPtr |= alpha;
                        destPtr++;
                    }
                }
                    return;

                case BufferFormat.B5G5R5A1_UIntNormal:
                {
                    var srcPtr  = (ushort *)src;
                    var destPtr = (ushort *)dest;

                    for (int i = 0; i < size; i += 2)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *(destPtr++) = (ushort)((*srcPtr++) | 0x8000);
                        }
                        else
                        {
                            *(destPtr++) |= 0x8000;
                        }
                    }
                }
                    return;

                case BufferFormat.A8_UIntNormal:
                    DirectAccess.FillMemory(dest, 0xFF, size);
                    return;
                }
            }

            // Copy if not doing an in-place update.
            if (dest != src)
            {
                DirectAccess.MemoryCopy(dest, src, size);
            }
        }
Exemple #5
0
        /// <summary>
        /// Function to copy (or update in-place) with bits swizzled to match another format.
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="format">Format of the destination buffer.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is NULL.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>Use this method to copy a single scanline and swizzle the bits of an image and (optionally) set an opaque constant alpha value.</remarks>
        protected unsafe void SwizzleScanline(void *src, int srcPitch, void *dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags)
        {
            int  size = srcPitch.Min(destPitch);
            uint r, g, b, a, pixel;

            if (src == null)
            {
                throw new ArgumentNullException("src");
            }

            if (dest == null)
            {
                throw new ArgumentNullException("dest");
            }

            if (format == BufferFormat.Unknown)
            {
                throw new ArgumentException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, BufferFormat.Unknown),
                                            "format");
            }

            var srcPtr  = (uint *)src;
            var destPtr = (uint *)dest;

            switch (format)
            {
            case BufferFormat.R10G10B10A2:
            case BufferFormat.R10G10B10A2_UInt:
            case BufferFormat.R10G10B10A2_UIntNormal:
            case BufferFormat.R10G10B10_XR_BIAS_A2_UIntNormal:
                for (int i = 0; i < size; i += 4)
                {
                    if (src != dest)
                    {
                        pixel = *(srcPtr++);
                    }
                    else
                    {
                        pixel = *(destPtr);
                    }

                    r = ((pixel & 0x3FF00000) >> 20);
                    g = (pixel & 0x000FFC00);
                    b = ((pixel & 0x000003FF) << 20);
                    a = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha) ? 0xC0000000 : pixel & 0xC0000000;

                    *destPtr = r | g | b | a;
                    destPtr++;
                }
                return;

            case BufferFormat.R8G8B8A8:
            case BufferFormat.R8G8B8A8_UIntNormal:
            case BufferFormat.R8G8B8A8_UIntNormal_sRGB:
            case BufferFormat.B8G8R8A8_UIntNormal:
            case BufferFormat.B8G8R8X8_UIntNormal:
            case BufferFormat.B8G8R8A8:
            case BufferFormat.B8G8R8A8_UIntNormal_sRGB:
            case BufferFormat.B8G8R8X8:
            case BufferFormat.B8G8R8X8_UIntNormal_sRGB:
                for (int i = 0; i < size; i += 4)
                {
                    if (src != dest)
                    {
                        pixel = *(srcPtr++);
                    }
                    else
                    {
                        pixel = *(destPtr);
                    }

                    r = ((pixel & 0xFF0000) >> 16);
                    g = (pixel & 0x00FF00);
                    b = ((pixel & 0x0000FF) << 16);
                    a = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha) ? 0xFF000000 : pixel & 0xFF000000;

                    *destPtr = r | g | b | a;
                    destPtr++;
                }
                return;
            }

            if (src != dest)
            {
                DirectAccess.MemoryCopy(dest, src, size);
            }
        }
 /// <summary>
 /// Function to copy the memory contents from this pointer to another.
 /// </summary>
 /// <param name="destination">Destination buffer.</param>
 /// <param name="source">Source buffer.</param>
 /// <param name="size">Size of the data to copy, in bytes.</param>
 /// <remarks>Since a pointer doesn't have a size associated with it, care must be taken to not overstep the bounds of the data pointed at by the pointer.</remarks>
 /// <exception cref="System.ArgumentNullException">Thrown when the destination pointer is NULL (Nothing in VB.Net).</exception>
 public static void CopyTo(this IntPtr source, IntPtr destination, int size)
 {
     DirectAccess.MemoryCopy(destination, source, size);
 }
Exemple #7
0
        /// <summary>
        /// Function to copy the image buffer data from this buffer into another.
        /// </summary>
        /// <param name="buffer">The buffer to copy into.</param>
        /// <param name="sourceRegion">[Optional] The region in the source to copy.</param>
        /// <param name="destX">[Optional] Horizontal offset in the destination buffer.</param>
        /// <param name="destY">[Optional] Vertical offset in the destination buffer.</param>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="buffer" /> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="buffer" /> is not the same format as this buffer.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the source region does not fit within the bounds of this buffer.</exception>
        /// <remarks>
        /// This method will copy the contents of this buffer into another buffer and will provide clipping to handle cases where the buffer or <paramref name="sourceRegion" /> is mismatched with the
        /// destination size.
        /// <para>Users may define an area on this buffer to copy by specifying the <paramref name="sourceRegion" /> parameter.  If NULL (Nothing in VB.Net) is passed to this parameter, then the
        /// entire buffer will be copied to the destination.</para><para>An offset into the destination buffer may also be specified to relocate the data copied from this buffer into the destination.  Clipping will be applied if the offset pushes the
        /// source data outside of the boundaries of the destination buffer.</para><para>The destination buffer must be the same format as the source buffer.  If it is not, then an exception will be thrown.</para>
        /// <para>The <paramref name="buffer"/> parameter must not be the same as the this buffer.  An exception will be thrown if an attempt to copy this buffer into itself is made.</para>
        /// <para>If the source region does not fit within the bounds of this buffer, then an exception will be thrown.</para>
        /// </remarks>
        public unsafe void CopyTo(GorgonImageBuffer buffer, Rectangle?sourceRegion = null, int destX = 0, int destY = 0)
        {
            var       sourceBufferDims = new Rectangle(0, 0, Width, Height);
            Rectangle srcRegion        = sourceRegion != null ? sourceRegion.Value : sourceBufferDims;

            if ((buffer == null) ||
                (buffer.Data == null) ||
                (buffer.Data.Length == 0))
            {
                throw new ArgumentNullException("buffer");
            }

            if ((buffer == this) ||
                (buffer.Data.UnsafePointer == Data.UnsafePointer))
            {
                throw new ArgumentException(Resources.GORGFX_IMAGE_BUFFER_CANT_BE_SAME, "buffer");
            }

            if (buffer.Format != Format)
            {
                throw new ArgumentException(Resources.GORGFX_IMAGE_MUST_BE_SAME_FORMAT, "buffer");
            }

            if (!sourceBufferDims.Contains(srcRegion))
            {
                throw new ArgumentOutOfRangeException("sourceRegion");
            }

            // If we try to place this image outside of the target buffer, then do nothing.
            if ((destX >= buffer.Width) ||
                (destY >= buffer.Height))
            {
                return;
            }

            // Adjust in case we're trying to move off the target.
            if (destX < 0)
            {
                srcRegion.X     -= destX;
                srcRegion.Width += destX;
                destX            = 0;
            }

            if (destY < 0)
            {
                srcRegion.Y      -= destY;
                srcRegion.Height += destY;
                destY             = 0;
            }

            // Ensure that the regions actually fit within their respective buffers.
            srcRegion = Rectangle.FromLTRB(srcRegion.X.Max(0), srcRegion.Y.Max(0), srcRegion.Right.Min(Width), srcRegion.Bottom.Min(Height));
            Rectangle dstRegion = Rectangle.FromLTRB(destX, destY, (destX + buffer.Width).Min(buffer.Width), (destY + buffer.Height).Min(buffer.Height));

            // If the source/dest region is empty, then we have nothing to copy.
            if ((srcRegion.IsEmpty) ||
                (dstRegion.IsEmpty) ||
                (dstRegion.Right < 0) ||
                (dstRegion.Bottom < 0))
            {
                return;
            }

            // If the buffers are identical in dimensions and have no offset, then just do a straight copy.
            if (srcRegion == dstRegion)
            {
                DirectAccess.MemoryCopy(buffer.Data.UnsafePointer, Data.UnsafePointer, (int)Data.Length);
                return;
            }

            // Find out how many bytes each pixel occupies.
            int dataSize = PitchInformation.RowPitch / Width;

            int srcLineSize = dataSize * srcRegion.Width;               // Number of source bytes/scanline.
            var srcData     = ((byte *)Data.UnsafePointer) + (srcRegion.Y * PitchInformation.RowPitch) + (srcRegion.X * dataSize);

            int dstLineSize = dataSize * dstRegion.Width;               // Number of dest bytes/scanline.
            var dstData     = ((byte *)buffer.Data.UnsafePointer) + (dstRegion.Y * buffer.PitchInformation.RowPitch) + (dstRegion.X * dataSize);

            // Get the smallest line size.
            int minLineSize = dstLineSize.Min(srcLineSize);
            int minHeight   = dstRegion.Height.Min(srcRegion.Height);

            // Finally, copy our data.
            for (int i = 0; i < minHeight; ++i)
            {
                DirectAccess.MemoryCopy(dstData, srcData, minLineSize);

                srcData += PitchInformation.RowPitch;
                dstData += buffer.PitchInformation.RowPitch;
            }
        }