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); }