Beispiel #1
0
        // ###############################################################################
        // ### 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);
        }