/// <summary> Draw the border. </summary>
        /// <param name="display"> The display pointer, that specifies the connection to the X server. <see cref="IntPtr"/> </param>
        /// <param name="window"> The window to draw on. <see cref="IntPtr"/> </param>
        /// <param name="gc"> The graphics context to use for drawing. <see cref="IntPtr"/> </param>
        /// <param name="borderArea"> The area to draw the border on. <see cref="TRectangle"/> </param>
        /// <param name="borderWidth"> The width of the border. <see cref="System.Int32"/> </param>
        public virtual void DrawBorder(IntPtr display, IntPtr window, IntPtr gc, TRectangle borderArea, int borderWidth)
        {
            if (display == IntPtr.Zero)
            {
                Console.WriteLine(CLASS_NAME + "::DrawOuterBorder () ERROR: Argument null: display");
                return;
            }
            if (window == IntPtr.Zero)
            {
                Console.WriteLine(CLASS_NAME + "::DrawOuterBorder () ERROR: Argument null: window");
                return;
            }
            if (gc == IntPtr.Zero)
            {
                Console.WriteLine(CLASS_NAME + "::DrawOuterBorder () ERROR: Argument null: gc");
                return;
            }

            if (borderWidth <= 0)
            {
                return;
            }

            for (int counter = 0; counter < (int)borderWidth; counter++)
            {
                // Top: L ==> R
                X11lib.XDrawLine(display, window, gc, (X11.TInt)(borderArea.Left + counter), (X11.TInt)(borderArea.Top + counter),
                                 (X11.TInt)((int)borderArea.Right - counter - 1), (X11.TInt)(borderArea.Top + counter));
                // Right: T ==> B
                X11lib.XDrawLine(display, window, gc, (X11.TInt)((int)borderArea.Right - counter - 1), (X11.TInt)(borderArea.Top + counter),
                                 (X11.TInt)((int)borderArea.Right - counter - 1), (X11.TInt)((int)borderArea.Bottom - counter - 1));
                // Bottom: R ==> L
                X11lib.XDrawLine(display, window, gc, (X11.TInt)((int)borderArea.Right - counter - 1), (X11.TInt)((int)borderArea.Bottom - counter - 1),
                                 (X11.TInt)(borderArea.Left + counter), (X11.TInt)((int)borderArea.Bottom - counter - 1));
                // Left: B ==> T
                X11lib.XDrawLine(display, window, gc, (X11.TInt)(borderArea.Left + counter), (X11.TInt)((int)borderArea.Bottom - counter - 1),
                                 (X11.TInt)(borderArea.Left + counter), (X11.TInt)(borderArea.Top + counter));
                // Fix X11lib drawing problems (not drawn pixel at bottom right corner).
                X11lib.XDrawPoint(display, window, gc, (X11.TInt)((int)borderArea.Right - (int)counter - 1), (X11.TInt)(borderArea.Bottom - (int)counter - 1));
            }
        }
        /// <summary> Draw the frame ( 3D effect). </summary>
        /// <param name="display"> The display pointer, that specifies the connection to the X server. <see cref="IntPtr"/> </param>
        /// <param name="window"> The window to draw on. <see cref="IntPtr"/> </param>
        /// <param name="gc"> The graphics context to use for drawing. <see cref="IntPtr"/> </param>
        /// <param name="clientArea"> The area to draw the shadow on. <see cref="TRectangle"/> </param>
        /// <param name="frameType"> The frame type to draw. <see cref="TFrameTypeExt"/> </param>
        /// <param name="darkShadow"> The X11 border pixel do use for dark shadow drawing. <see cref="TPixel"/> </param>
        /// <param name="lightShadow"> The X11 border pixel do use for light shadow drawing.<see cref="TPixel"/> </param>
        internal virtual void DrawFrame(IntPtr display, IntPtr window, IntPtr gc, TRectangle clientArea, TFrameTypeExt frameType, TPixel darkShadow, TPixel lightShadow)
        {
            if (display == IntPtr.Zero)
            {
                Console.WriteLine(CLASS_NAME + "::DrawFrame () ERROR: Argument null: display");
                return;
            }
            if (window == IntPtr.Zero)
            {
                Console.WriteLine(CLASS_NAME + "::DrawFrame () ERROR: Argument null: window");
                return;
            }
            if (gc == IntPtr.Zero)
            {
                Console.WriteLine(CLASS_NAME + "::DrawFrame () ERROR: Argument null: gc");
                return;
            }

            if (frameType == TFrameTypeExt.None)
            {
                return;
            }

            X11lib.XGCValues xgcValues = new X11lib.XGCValues();
            xgcValues.line_width = (X11.TInt) 1;
            TUint xgcMask = (TUint)(X11lib.GCattributemask.GCLineWidth);

            X11lib.XChangeGC(display, gc, xgcMask, ref xgcValues);

            if (frameType == TFrameTypeExt.Raised || frameType == TFrameTypeExt.Sunken ||
                frameType == TFrameTypeExt.RaisedTopTab || frameType == TFrameTypeExt.RaisedLeftTab ||
                frameType == TFrameTypeExt.RaisedRightTab || frameType == TFrameTypeExt.RaisedBottomTab ||
                frameType == TFrameTypeExt.RaisedTopTabTail || frameType == TFrameTypeExt.SunkenTopTabTail ||
                frameType == TFrameTypeExt.UnraisedTopTab || frameType == TFrameTypeExt.UnraisedLeftTab ||
                frameType == TFrameTypeExt.UnraisedRightTab || frameType == TFrameTypeExt.UnraisedBottomTab ||
                frameType == TFrameTypeExt.UnraisedTopTabTail || frameType == TFrameTypeExt.UnsunkenTopTabTail ||
                frameType == TFrameTypeExt.SunkenTopTab || frameType == TFrameTypeExt.SunkenLeftTab ||
                frameType == TFrameTypeExt.SunkenRightTab || frameType == TFrameTypeExt.SunkenBottomTab ||
                frameType == TFrameTypeExt.UnsunkenTopTab || frameType == TFrameTypeExt.UnsunkenLeftTab ||
                frameType == TFrameTypeExt.UnsunkenRightTab || frameType == TFrameTypeExt.UnsunkenBottomTab)
            {
                bool raised = true;

                if (frameType == TFrameTypeExt.Sunken ||
                    frameType == TFrameTypeExt.SunkenTopTab || frameType == TFrameTypeExt.SunkenTopTabTail ||
                    frameType == TFrameTypeExt.SunkenLeftTab || frameType == TFrameTypeExt.SunkenRightTab ||
                    frameType == TFrameTypeExt.SunkenBottomTab ||
                    frameType == TFrameTypeExt.UnsunkenTopTab || frameType == TFrameTypeExt.UnsunkenTopTabTail ||
                    frameType == TFrameTypeExt.UnsunkenLeftTab || frameType == TFrameTypeExt.UnsunkenRightTab ||
                    frameType == TFrameTypeExt.UnsunkenBottomTab)
                {
                    raised = false;
                }

                // Right and bottom edge.
                X11lib.XSetForeground(display, gc, (raised ? darkShadow : lightShadow));
                for (int width = 0; width < _frameWidth; width++)
                {
                    // Right.
                    if (frameType != TFrameTypeExt.RaisedLeftTab && frameType != TFrameTypeExt.SunkenLeftTab &&
                        frameType != TFrameTypeExt.UnraisedRightTab && frameType != TFrameTypeExt.UnraisedTopTab &&
                        frameType != TFrameTypeExt.UnraisedTopTabTail && frameType != TFrameTypeExt.UnraisedBottomTab &&
                        frameType != TFrameTypeExt.UnsunkenRightTab && frameType != TFrameTypeExt.UnsunkenTopTab &&
                        frameType != TFrameTypeExt.UnsunkenTopTabTail && frameType != TFrameTypeExt.UnsunkenBottomTab)
                    {
                        if (frameType == TFrameTypeExt.UnraisedLeftTab || frameType == TFrameTypeExt.UnsunkenLeftTab)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Top - 1,
                                             (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom + 1);
                        }
                        else if (frameType == TFrameTypeExt.RaisedTopTab || frameType == TFrameTypeExt.SunkenTopTab ||
                                 frameType == TFrameTypeExt.RaisedTopTabTail || frameType == TFrameTypeExt.SunkenTopTabTail)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Top,
                                             (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom);
                        }
                        else if (frameType == TFrameTypeExt.RaisedBottomTab || frameType == TFrameTypeExt.SunkenBottomTab)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Top - 1,
                                             (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom);
                        }
                        else
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Top + width,
                                             (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom - width);
                        }
                    }
                    // Bottom.
                    if (frameType != TFrameTypeExt.RaisedTopTab && frameType != TFrameTypeExt.RaisedTopTabTail &&
                        frameType != TFrameTypeExt.SunkenTopTab && frameType != TFrameTypeExt.SunkenTopTabTail &&
                        frameType != TFrameTypeExt.UnraisedBottomTab && frameType != TFrameTypeExt.UnraisedLeftTab && frameType != TFrameTypeExt.UnraisedRightTab &&
                        frameType != TFrameTypeExt.UnsunkenBottomTab && frameType != TFrameTypeExt.UnsunkenLeftTab && frameType != TFrameTypeExt.UnsunkenRightTab)
                    {
                        if (frameType == TFrameTypeExt.UnraisedTopTab || frameType == TFrameTypeExt.UnraisedTopTabTail ||
                            frameType == TFrameTypeExt.UnsunkenTopTab || frameType == TFrameTypeExt.UnsunkenTopTabTail)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left - 1, (TInt)clientArea.Bottom - 1 - width,
                                             (TInt)clientArea.Right - 1 + 1, (TInt)clientArea.Bottom - 1 - width);
                        }
                        else
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Bottom - 1 - width,
                                             (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom - 1 - width);
                        }
                    }
                }

                // Top and Left edge.
                X11lib.XSetForeground(display, gc, (raised ? lightShadow : darkShadow));
                for (int width = 0; width < _frameWidth; width++)
                {
                    // Top.
                    if (frameType != TFrameTypeExt.RaisedBottomTab && frameType != TFrameTypeExt.SunkenBottomTab &&
                        frameType != TFrameTypeExt.UnraisedTopTab && frameType != TFrameTypeExt.UnraisedTopTabTail &&
                        frameType != TFrameTypeExt.UnraisedLeftTab && frameType != TFrameTypeExt.UnraisedRightTab &&
                        frameType != TFrameTypeExt.UnsunkenTopTab && frameType != TFrameTypeExt.UnsunkenTopTabTail &&
                        frameType != TFrameTypeExt.UnsunkenLeftTab && frameType != TFrameTypeExt.UnsunkenRightTab)
                    {
                        if (frameType == TFrameTypeExt.UnraisedBottomTab || frameType == TFrameTypeExt.UnsunkenBottomTab)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left - 1, (TInt)clientArea.Top + width,
                                             (TInt)clientArea.Right + 1, (TInt)clientArea.Top + width);
                        }
                        else
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top + width,
                                             (TInt)clientArea.Right - width, (TInt)clientArea.Top + width);
                        }
                    }
                    // Left.
                    if (frameType != TFrameTypeExt.RaisedRightTab && frameType != TFrameTypeExt.SunkenRightTab &&
                        frameType != TFrameTypeExt.UnraisedLeftTab && frameType != TFrameTypeExt.UnraisedTopTab &&
                        frameType != TFrameTypeExt.UnraisedTopTabTail && frameType != TFrameTypeExt.UnraisedBottomTab &&
                        frameType != TFrameTypeExt.UnsunkenLeftTab && frameType != TFrameTypeExt.UnsunkenTopTab &&
                        frameType != TFrameTypeExt.UnsunkenTopTabTail && frameType != TFrameTypeExt.UnsunkenBottomTab)
                    {
                        if (frameType == TFrameTypeExt.UnraisedRightTab || frameType == TFrameTypeExt.UnsunkenRightTab)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top - 1,
                                             (TInt)clientArea.Left + width, (TInt)clientArea.Bottom + 1);
                        }
                        else if (frameType == TFrameTypeExt.RaisedTopTab || frameType == TFrameTypeExt.SunkenTopTab ||
                                 frameType == TFrameTypeExt.RaisedTopTabTail || frameType == TFrameTypeExt.SunkenTopTabTail)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top,
                                             (TInt)clientArea.Left + width, (TInt)clientArea.Bottom + 1);
                        }
                        else if (frameType == TFrameTypeExt.RaisedBottomTab || frameType == TFrameTypeExt.SunkenBottomTab)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top - 1,
                                             (TInt)clientArea.Left + width, (TInt)clientArea.Bottom - width);
                        }
                        else
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top + width,
                                             (TInt)clientArea.Left + width, (TInt)clientArea.Bottom - width);
                        }
                    }
                }
                // Finish right bottom edge.
                if (frameType == TFrameTypeExt.RaisedTopTab || frameType == TFrameTypeExt.SunkenTopTab)
                {
                    X11lib.XSetForeground(display, gc, (raised ? lightShadow : darkShadow));
                    for (int width = 0; width < _frameWidth; width++)
                    {
                        if (width >= 1)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - _frameWidth + width, (TInt)clientArea.Bottom - width,
                                             (TInt)clientArea.Right - _frameWidth + width, (TInt)clientArea.Bottom);
                        }
                    }
                }
                if (frameType == TFrameTypeExt.UnraisedTopTabTail || frameType == TFrameTypeExt.UnsunkenTopTabTail)
                {
                    X11lib.XSetForeground(display, gc, (raised ? lightShadow : darkShadow));
                    for (int width = 0; width < _frameWidth; width++)
                    {
                        if (width >= 1)
                        {
                            X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - _frameWidth + width, (TInt)clientArea.Bottom - width,
                                             (TInt)clientArea.Right - _frameWidth + width, (TInt)clientArea.Bottom);
                        }
                    }
                }
                // Finish top left edge.
                // else if (frameType == TFrameTypeExt.RaisedBottomTab     || frameType == TFrameTypeExt.SunkenBottomTab)
            }
            else if (frameType == TFrameTypeExt.Chiseled || frameType == TFrameTypeExt.Ledged)
            {
                int halfWidth = _frameWidth / 2;

                // Bottom and right edge.
                X11lib.XSetForeground(display, gc, (frameType == TFrameTypeExt.Chiseled ? lightShadow : darkShadow));
                for (int width = 0; width < halfWidth; width++)
                {
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Top + width,
                                     (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom - width);
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Bottom - 1 - width,
                                     (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom - 1 - width);
                }
                X11lib.XSetForeground(display, gc, (frameType == TFrameTypeExt.Chiseled ? darkShadow : lightShadow));
                for (int width = halfWidth; width < _frameWidth; width++)
                {
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Top + width,
                                     (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom - width);
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Bottom - 1 - width,
                                     (TInt)clientArea.Right - 1 - width, (TInt)clientArea.Bottom - 1 - width);
                }

                // Top and left edge.
                X11lib.XSetForeground(display, gc, (frameType == TFrameTypeExt.Chiseled ? darkShadow : lightShadow));
                for (int width = 0; width < halfWidth; width++)
                {
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top + width,
                                     (TInt)clientArea.X + width, (TInt)clientArea.Bottom - width);
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top + width,
                                     (TInt)clientArea.Right - width, (TInt)clientArea.Top + width);
                }
                X11lib.XSetForeground(display, gc, (frameType == TFrameTypeExt.Chiseled ? lightShadow : darkShadow));
                for (int width = halfWidth; width < _frameWidth; width++)
                {
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top + width,
                                     (TInt)clientArea.X + width, (TInt)clientArea.Bottom - width);
                    X11lib.XDrawLine(display, window, gc, (TInt)clientArea.Left + width, (TInt)clientArea.Top + width,
                                     (TInt)clientArea.Right - width, (TInt)clientArea.Top + width);
                }
            }
        }