private void ProcessMonoMask(DeviceContextProxy context,
                                             bool isMono, ref PointerInfo info, out int width, out int height, out int left, out int top)
                {
                    var deskWidth  = sharedDescription.Width;
                    var deskHeight = sharedDescription.Height;
                    var givenLeft  = info.Position.X;
                    var givenTop   = info.Position.Y;

                    if (givenLeft < 0)
                    {
                        width = givenLeft + info.ShapeInfo.Width;
                    }
                    else if (givenLeft + info.ShapeInfo.Width > deskWidth)
                    {
                        width = deskWidth - givenLeft;
                    }
                    else
                    {
                        width = info.ShapeInfo.Width;
                    }

                    if (isMono)
                    {
                        info.ShapeInfo.Height /= 2;
                    }

                    if (givenTop < 0)
                    {
                        height = givenTop + info.ShapeInfo.Height;
                    }
                    else if (givenTop + info.ShapeInfo.Height > deskHeight)
                    {
                        height = deskHeight - givenTop;
                    }
                    else
                    {
                        height = info.ShapeInfo.Height;
                    }

                    if (isMono)
                    {
                        info.ShapeInfo.Height *= 2;
                    }

                    left = givenLeft < 0 ? 0 : givenLeft;
                    top  = givenTop < 0 ? 0 : givenTop;
                    stageTextureDesc.Width  = width;
                    stageTextureDesc.Height = height;
                    if (initBuffer.Length != width * height * BPP)
                    {
                        initBuffer = new byte[width * height * BPP];
                    }

                    if (copyBuffer == null || stageTextureDesc.Width != width || stageTextureDesc.Height != height)
                    {
                        RemoveAndDispose(ref copyBuffer);
                        copyBuffer = new Texture2D(context, stageTextureDesc);
                    }

                    context.CopySubresourceRegion(SharedTexture, 0,
                                                  new global::SharpDX.Direct3D11.ResourceRegion(left, top, 0, left + width, top + height, 1), copyBuffer, 0);

                    var dataBox = context.MapSubresource(copyBuffer, 0, global::SharpDX.Direct3D11.MapMode.Read, global::SharpDX.Direct3D11.MapFlags.None);

                    #region process
                    unsafe // Call unmanaged code
                    {
                        fixed(byte *initBufferPtr = initBuffer)
                        {
                            var initBuffer32         = (uint *)initBufferPtr;
                            var desktop32            = (uint *)dataBox.DataPointer;
                            var desktopPitchInPixels = dataBox.RowPitch / sizeof(int);
                            var skipX = (givenLeft < 0) ? (uint)(-1 * givenLeft) : 0;
                            var skipY = (givenTop < 0) ? (uint)(-1 * givenTop) : 0;

                            if (isMono)
                            {
                                for (var row = 0; row < stageTextureDesc.Height; ++row)
                                {
                                    // Set mask
                                    byte Mask = 0x80;
                                    Mask = (byte)(Mask >> (byte)(skipX % 8));
                                    for (var col = 0; col < stageTextureDesc.Width; ++col)
                                    {
                                        // Get masks using appropriate offsets
                                        var AndMask = (byte)(info.PtrShapeBuffer[((col + skipX) / 8) + ((row + skipY) * (info.ShapeInfo.Pitch))] & Mask);
                                        var XorMask = (byte)(info.PtrShapeBuffer[((col + skipX) / 8) + ((row + skipY + (info.ShapeInfo.Height / 2))
                                                                                                        * (info.ShapeInfo.Pitch))] & Mask);
                                        var AndMask32 = (AndMask > 0) ? 0xFFFFFFFF : 0xFF000000;
                                        var XorMask32 = (XorMask > 0) ? (uint)0x00FFFFFF : 0x00000000;

                                        // Set new pixel
                                        initBuffer32[(row * stageTextureDesc.Width) + col] = (desktop32[(row * desktopPitchInPixels) + col] & AndMask32) ^ XorMask32;

                                        // Adjust mask
                                        if (Mask == 0x01)
                                        {
                                            Mask = 0x80;
                                        }
                                        else
                                        {
                                            Mask = (byte)(Mask >> 1);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                fixed(byte *shapeBufferPtr = info.PtrShapeBuffer)
                                {
                                    var Buffer32 = (uint *)shapeBufferPtr;

                                    // Iterate through pixels
                                    for (var row = 0; row < stageTextureDesc.Height; ++row)
                                    {
                                        for (var col = 0; col < stageTextureDesc.Width; ++col)
                                        {
                                            // Set up mask
                                            var MaskVal = 0xFF000000 & Buffer32[(col + skipX) + ((row + skipY) * (info.ShapeInfo.Pitch / sizeof(uint)))];
                                            if (MaskVal > 0)
                                            {
                                                // Mask was 0xFF
                                                initBuffer32[(row * stageTextureDesc.Width) + col] = (desktop32[(row * desktopPitchInPixels) + col]
                                                                                                      ^ Buffer32[(col + skipX) + ((row + skipY) * (info.ShapeInfo.Pitch / sizeof(uint)))]) | 0xFF000000;
                                            }
                                            else
                                            {
                                                // Mask was 0x00
                                                initBuffer32[(row * stageTextureDesc.Width) + col]
                                                    = Buffer32[(col + skipX) + ((row + skipY) * (info.ShapeInfo.Pitch / sizeof(uint)))] | 0xFF000000;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                    context.UnmapSubresource(copyBuffer, 0);
                }