// ############################################################################### // ### C O N S T R U C T I O N A N D I N I T I A L I Z A T I O N // ############################################################################### #region Construction /// <summary>Initializing constructor.</summary> /// <param name="display">The display pointer, that specifies the connection to the X server.<see cref="System.IntPtr"/></param> /// <param name="screenNumber">The appropriate screen number on the host server.<see cref="System.Int32"/></param> /// <param name="colormap">The X11 colormap pointer.<see cref="IntPtr"/></param> /// <param name="graphicDepth">The depth (number of planes) of the graphic - that holds color pixel information.<see cref="System.Int32"/></para> /// <param name="width">The width of the image to create.<see cref="System.Int32"/></param> /// <param name="height">The height of the image to create.<see cref="System.Int32"/></param> public X11Image(IntPtr display, int screenNumber, IntPtr colormap, int graphicDepth, int width, int height) { if (display == IntPtr.Zero) { throw new ArgumentNullException("display"); } if (colormap == IntPtr.Zero) { throw new ArgumentNullException("colormap"); } IntPtr rootWindow = X11lib.XRootWindow(display, (X11.TInt)screenNumber); IntPtr rootVisual = X11lib.XDefaultVisual(display, (X11.TInt)screenNumber); if (rootVisual == IntPtr.Zero) { throw new NullReferenceException("rootVisual"); } IntPtr imageXPixmap = X11lib.XCreatePixmap(display, rootWindow, (X11.TUint)width, (X11.TUint)height, (X11.TUint)graphicDepth); if (imageXPixmap == IntPtr.Zero) { throw new NullReferenceException("imageXPixmap"); } _size.Width = width; _size.Height = height; _imageSurface = new X11Surface(display, screenNumber, imageXPixmap, rootVisual, graphicDepth, colormap); }
/// <summary> Draw the image in the indicated window, using the indicated graphics context. </summary> /// <param name="window"> The window to draw the pitmap on. <see cref="System.IntPtr"/> </param> /// <param name="gc"> The crapchics context to use for drawing. <see cref="System.IntPtr"/> </param> /// <param name="destX"> The x coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> /// <param name="destY"> The y coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> public void Draw(IntPtr window, IntPtr gc, TInt dstX, TInt dstY) { // Possible optimization: Keep the graphicGc between the exposure events. // Problem: Every graphic allocates a graphics context (limited server resource). if (_transpXImage != IntPtr.Zero) { // Prepare the clip mask (for transparency) that must be a XPixmap. if (_transpXPixmap == IntPtr.Zero) { // Server side storage. _transpXPixmap = X11lib.XCreatePixmap(_display, window, (TUint)_width, (TUint)_height, (TUint)_clipDepth); IntPtr maskGc = X11lib.XCreateGC(_display, _transpXPixmap, (TUlong)0, IntPtr.Zero); if (maskGc != IntPtr.Zero) { X11lib.XPutImage(_display, _transpXPixmap, maskGc, _transpXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Console.WriteLine (CLASS_NAME + "::Draw () Delete transparency mask image GC."); X11lib.XFreeGC(_display, maskGc); maskGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::Draw () ERROR: Can not create graphics context for mask pixmap."); } } // Prepare the clipping graphics context. IntPtr graphicGc = X11lib.XCreateGC(_display, window, (TUlong)0, IntPtr.Zero); if (graphicGc != IntPtr.Zero) { X11lib.XSetClipMask(_display, graphicGc, _transpXPixmap); X11lib.XSetClipOrigin(_display, graphicGc, dstX, dstY); // Draw graphic using the clipping graphics context. X11lib.XPutImage(_display, window, graphicGc, _graphicXImage, (TInt)0, (TInt)0, (TInt)dstX, (TInt)dstY, (TUint)_width, (TUint)_height); // Restore previous behaviour and clean up. X11lib.XSetClipMask(_display, graphicGc, IntPtr.Zero); X11lib.XSetClipOrigin(_display, graphicGc, (TInt)0, (TInt)0); // Console.WriteLine (CLASS_NAME + "::Draw () Delete clipping image GC."); X11lib.XFreeGC(_display, graphicGc); graphicGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::Draw () ERROR: Can not create graphics context for transparency application."); } } else { X11lib.XPutImage(_display, window, gc, _graphicXImage, 0, 0, dstX, dstY, (TUint)_width, (TUint)_height); } }
// ############################################################################### // ### M E T H O D S // ############################################################################### #region Methods /// <summary> Draw the image in the indicated window, using the indicated graphics context. </summary> /// <param name="window"> The window to draw the pitmap on. <see cref="System.IntPtr"/> </param> /// <param name="gc"> The crapchics context to use for drawing. <see cref="System.IntPtr"/> </param> /// <param name="destX"> The x coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> /// <param name="destY"> The y coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> private void DrawUnfinished(IntPtr window, IntPtr gc, TInt dstX, TInt dstY) { // This is an alternative drawing approach, but i didn't get it working. IntPtr clipPixmap = X11lib.XCreatePixmap(_display, window, (TUint)_width, (TUint)_height, (TUint)_clipDepth); IntPtr clipGc = X11lib.XCreateGC(_display, clipPixmap, (TUlong)0, IntPtr.Zero); X11lib.XPutImage(_display, clipPixmap, clipGc, _transpXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); X11lib.XSetFunction(_display, gc, X11lib.XGCFunction.GXand); X11lib.XSetBackground(_display, gc, (TPixel)1); X11lib.XSetForeground(_display, gc, (TPixel)0); X11lib.XCopyPlane(_display, clipPixmap, window, gc, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height, (TInt)dstX, (TInt)dstY, (TUlong)1); }
/// <summary> Provide a bitmap, containing the transparency mask, that can be used independent from this class. </summary> /// <param name="display"> The display pointer, that specifies the connection to the X server. <see cref="System.IntPtr"/> </param> /// <param name="window"> The target window to create the pixmap for. <see cref="IntPtr"/> </param> /// <returns> The (server side) pixmap (that must be feed) on success, or IntPtr.Zero otherwise. <see cref="IntPtr"/> </returns> public IntPtr CreateIndependentMaskPixmap(IntPtr display, IntPtr window) { if (_transpXImage == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr pixmap = X11lib.XCreatePixmap(display, window, (TUint)_width, (TUint)_height, (TUint)_clipDepth); IntPtr pixmapGc = X11lib.XCreateGC(display, pixmap, (TUlong)0, IntPtr.Zero); if (pixmapGc != IntPtr.Zero) { X11lib.XPutImage(display, pixmap, pixmapGc, _transpXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Console.WriteLine (CLASS_NAME + "::CreateIndependentMaskPixmap () Delete transparency mask image GC."); X11lib.XFreeGC(display, pixmapGc); pixmapGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::CreateIndependentMaskPixmap () ERROR: Can not create graphics context for mask pixmap."); } return(pixmap); }
/// <summary> Provide a bitmap, containing the transparent graphic, that can be used independent from this class. </summary> /// <param name="display"> The display pointer, that specifies the connection to the X server. <see cref="System.IntPtr"/> </param> /// <param name="window"> The target window to create the pixmap for. <see cref="IntPtr"/> </param> /// <param name="backgroundColorPixel"> The background color behind any transparent pixel. <see cref="TPixel"/> </param> /// <param name="maskPixmap"> The mask pixmap to distinguish transparent from intransparent pixel. <see cref="IntPtr"/> </param> /// <returns> The (server side) pixmap (that must be feed) on success, or IntPtr.Zero otherwise. <see cref="IntPtr"/> </returns> public IntPtr CreateIndependentPixmap(IntPtr display, IntPtr window, TPixel backgroundColorPixel, IntPtr maskPixmap) { if (_graphicXImage == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr pixmap = X11lib.XCreatePixmap(display, window, (TUint)_width, (TUint)_height, (TUint)_graphicDepth); // Fill pixmap with background color. IntPtr bgGc = X11lib.XCreateGC(display, window, (TUlong)0, IntPtr.Zero); X11lib.XSetForeground(display, bgGc, backgroundColorPixel); X11lib.XFillRectangle(display, pixmap, bgGc, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); X11lib.XFreeGC(display, bgGc); bgGc = IntPtr.Zero; // Overlay the image. IntPtr pixmapGc = X11lib.XCreateGC(display, window, (TUlong)0, IntPtr.Zero); if (pixmapGc != IntPtr.Zero) { if (maskPixmap != IntPtr.Zero) { // Prepare the clipping graphics context. IntPtr graphicGc = X11lib.XCreateGC(display, window, (TUlong)0, IntPtr.Zero); if (graphicGc != IntPtr.Zero) { X11lib.XSetClipMask(display, graphicGc, maskPixmap); X11lib.XSetClipOrigin(display, graphicGc, (TInt)0, (TInt)0); // Draw graphic using the clipping graphics context. X11lib.XPutImage(display, pixmap, graphicGc, _graphicXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Restore previous behaviour and clean up. X11lib.XSetClipMask(display, graphicGc, IntPtr.Zero); X11lib.XSetClipOrigin(display, graphicGc, (TInt)0, (TInt)0); // Console.WriteLine (CLASS_NAME + "::Draw () Delete clipping image GC."); X11lib.XFreeGC(display, graphicGc); graphicGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::Draw () ERROR: Can not create graphics context for transparency application."); } } else { X11lib.XPutImage(display, pixmap, pixmapGc, _graphicXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Console.WriteLine (CLASS_NAME + "::CreateIndependentGraphicPixmap () Delete graphic image GC."); X11lib.XFreeGC(display, pixmapGc); pixmapGc = IntPtr.Zero; } } else { Console.WriteLine(CLASS_NAME + "::CreateIndependentGraphicPixmap () ERROR: Can not create graphics context for graphic pixmap."); } return(pixmap); }