/// <summary> Initialize local ressources for all constructors. </summary> /// <param name="bmp"> The bitmap associated with this graphic. <see cref="Bitmap"/> </param> private void InitializeGraphicRessources(Bitmap bmp) { IntPtr visual = X11lib.XDefaultVisual(_display, _screenNumber); if (visual == IntPtr.Zero) { throw new OperationCanceledException("Failed to investigate default visual."); } _width = bmp.Width; _height = bmp.Height; // Prepare bitmap conversion. int colorPixelBytes = 4; int maskLineBytes = (int)((_width + (int)IMAGE_PADDING - 1) / (int)IMAGE_PADDING); _graphicDepth = (int)X11lib.XDefaultDepth(_display, _screenNumber); if (_graphicDepth > 16) { colorPixelBytes = 4; } else if (_graphicDepth > 8) { colorPixelBytes = 2; } else { colorPixelBytes = 1; } // ### Allocate bitmap conversion data. // The bitmap color data. Use a temporary managed byte array for speed. byte[] graphicData = new byte[_height * _width * colorPixelBytes]; // The bitmap transparency data. Use a temporary managed byte array for speed. byte[] maskData = new byte[_height * maskLineBytes]; // Quick access to current line's color pixel. int graphicPixelIndex = 0; // Quick access to current line's mask pixel. int maskPixelIndex = 0; // Reduce slow calls to bmp.GetPixel (x,y). Color pixelColor = Color.Black; // Determine whether transparency is required. bool transparency = false; // ### Convert bitmap. for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { graphicPixelIndex = (y * _width + x) << 2; maskPixelIndex = y * maskLineBytes + (x >> 3); pixelColor = bmp.GetPixel(x, y); graphicData[graphicPixelIndex + 0] = pixelColor.B; // B graphicData[graphicPixelIndex + 1] = pixelColor.G; // G graphicData[graphicPixelIndex + 2] = pixelColor.R; // R graphicData[graphicPixelIndex + 3] = pixelColor.A; // A if (pixelColor.B == 255 && pixelColor.G == 255 && pixelColor.R == 255) { byte summand = (byte)(1 << (x % 8)); maskData[maskPixelIndex] = (byte)(maskData[maskPixelIndex] + summand); transparency = true; } } } // ### Create XImage. // The bitmap color data. IntPtr graphicDataHandle = Marshal.AllocHGlobal(graphicData.Length); // Allocate not movable memory. Marshal.Copy(graphicData, 0, graphicDataHandle, graphicData.Length); // Client side XImage storage. _graphicXImage = X11lib.XCreateImage(_display, visual, (TUint)_graphicDepth, X11lib.TImageFormat.ZPixmap, (TInt)0, graphicDataHandle, (TUint)_width, (TUint)_height, IMAGE_PADDING, ASSUME_CONTIGUOUS); if (_graphicXImage == IntPtr.Zero) { throw new OperationCanceledException("Image creation for graphic failed."); } if (transparency == true) { IntPtr maskDataHandle = Marshal.AllocHGlobal(maskData.Length); // The bitmap bitmap transparency data. Marshal.Copy(maskData, 0, maskDataHandle, maskData.Length); // Allocate not movable memory. // Client side storage. _transpXImage = X11lib.XCreateImage(_display, visual, (TUint)_clipDepth, X11lib.TImageFormat.XYBitmap, (TInt)0, maskDataHandle, (TUint)_width, (TUint)_height, IMAGE_PADDING, ASSUME_CONTIGUOUS); if (_transpXImage == IntPtr.Zero) { throw new OperationCanceledException("Image creation for transparency mask failed."); } } }