/// <summary>
        /// Create a MAPPED_GEOMETRY_PACKET
        /// </summary>
        /// <param name="mappingId">The id for the geometry mapping.</param>
        /// <param name="updateType">The update type.</param>
        /// <param name="left">The position to left bound.</param>
        /// <param name="top">The position to right bound.</param>
        /// <param name="width">The width of the rect.</param>
        /// <param name="height">The height of the rect.</param>
        /// <returns>MAPPED_GEOMETRY_PACKET created</returns>
        public MAPPED_GEOMETRY_PACKET CreateMappedGeometryPacket(UInt64 mappingId, UpdateTypeValues updateType, uint left, uint top, uint width, uint height)
        {
            MAPPED_GEOMETRY_PACKET geometry = new MAPPED_GEOMETRY_PACKET();

            if (updateType == UpdateTypeValues.GEOMETRY_UPDATE)
            {
                geometry.cbGeometryData = 0x79;
                geometry.Version = RdpegtVersionValues.RDP8;
                geometry.MappingId = mappingId;
                geometry.UpdateType = updateType;
                geometry.Flags = 0x0;
                geometry.TopLevelId = mappingId;
                geometry.Left = 0;
                geometry.Top = 0;
                geometry.Right = width;
                geometry.Bottom = height;
                geometry.TopLevelLeft = left;
                geometry.TopLevelTop = top;
                geometry.TopLevelRight = (uint)(left + width); ;
                geometry.TopLevelBottom = (uint)(top + height); ;
                geometry.GeometryType = GeometryTypeValues.RDP8;
                geometry.cbGeometryBuffer = 0x0030;
                geometry.pGeometryBuffer = new RGNDATA();
                geometry.pGeometryBuffer.rdh.dwSize = 32;
                geometry.pGeometryBuffer.rdh.iType = 0x0001;
                geometry.pGeometryBuffer.rdh.nCount = 0x0001;
                geometry.pGeometryBuffer.rdh.nRgnSize = 0;
                geometry.pGeometryBuffer.rdh.rcBound.left = (int)left;
                geometry.pGeometryBuffer.rdh.rcBound.top = (int)top;
                geometry.pGeometryBuffer.rdh.rcBound.right = (int)(left + width);
                geometry.pGeometryBuffer.rdh.rcBound.bottom = (int)(top + height);
                geometry.pGeometryBuffer.Buffer = new RECT[1];
                RECT rct = new RECT();
                rct.left = 0;
                rct.top = 0;
                rct.right = (int)width;
                rct.bottom = (int)height;
                geometry.pGeometryBuffer.Buffer[0] = rct;
                geometry.Reserved2 = 0;
            }
            else if (updateType == UpdateTypeValues.GEOMETRY_CLEAR)
            {
                geometry.cbGeometryData = 0x0049;
                geometry.Version = RdpegtVersionValues.RDP8;
                geometry.MappingId = mappingId;
                geometry.UpdateType = updateType;
                geometry.cbGeometryBuffer = 0;
                geometry.Reserved2 = 0;
            }

            return geometry;
        }
        // RDPEGT only contains a server-to-client message, server receive nothing

        #endregion Send/Receive Methods

        #region Create Methods

        /// <summary>
        /// Create a MAPPED_GEOMETRY_PACKET
        /// </summary>
        /// <param name="mappingId">The id for the geometry mapping.</param>
        /// <param name="updateType">The update type.</param>
        /// <param name="left">The position to left bound.</param>
        /// <param name="top">The position to right bound.</param>
        /// <param name="width">The width of the rect.</param>
        /// <param name="height">The height of the rect.</param>
        /// <returns>MAPPED_GEOMETRY_PACKET created</returns>
        public MAPPED_GEOMETRY_PACKET CreateMappedGeometryPacket(UInt64 mappingId, UpdateTypeValues updateType, uint left, uint top, uint width, uint height)
        {
            MAPPED_GEOMETRY_PACKET geometry = new MAPPED_GEOMETRY_PACKET();

            if (updateType == UpdateTypeValues.GEOMETRY_UPDATE)
            {
                geometry.cbGeometryData                     = 0x79;
                geometry.Version                            = RdpegtVersionValues.RDP8;
                geometry.MappingId                          = mappingId;
                geometry.UpdateType                         = updateType;
                geometry.Flags                              = 0x0;
                geometry.TopLevelId                         = mappingId;
                geometry.Left                               = 0;
                geometry.Top                                = 0;
                geometry.Right                              = width;
                geometry.Bottom                             = height;
                geometry.TopLevelLeft                       = left;
                geometry.TopLevelTop                        = top;
                geometry.TopLevelRight                      = (uint)(left + width);;
                geometry.TopLevelBottom                     = (uint)(top + height);;
                geometry.GeometryType                       = GeometryTypeValues.RDP8;
                geometry.cbGeometryBuffer                   = 0x0030;
                geometry.pGeometryBuffer                    = new RGNDATA();
                geometry.pGeometryBuffer.rdh.dwSize         = 32;
                geometry.pGeometryBuffer.rdh.iType          = 0x0001;
                geometry.pGeometryBuffer.rdh.nCount         = 0x0001;
                geometry.pGeometryBuffer.rdh.nRgnSize       = 0;
                geometry.pGeometryBuffer.rdh.rcBound.left   = (int)left;
                geometry.pGeometryBuffer.rdh.rcBound.top    = (int)top;
                geometry.pGeometryBuffer.rdh.rcBound.right  = (int)(left + width);
                geometry.pGeometryBuffer.rdh.rcBound.bottom = (int)(top + height);
                geometry.pGeometryBuffer.Buffer             = new RECT[1];
                RECT rct = new RECT();
                rct.left   = 0;
                rct.top    = 0;
                rct.right  = (int)width;
                rct.bottom = (int)height;
                geometry.pGeometryBuffer.Buffer[0] = rct;
                geometry.Reserved2 = 0;
            }
            else if (updateType == UpdateTypeValues.GEOMETRY_CLEAR)
            {
                geometry.cbGeometryData   = 0x0049;
                geometry.Version          = RdpegtVersionValues.RDP8;
                geometry.MappingId        = mappingId;
                geometry.UpdateType       = updateType;
                geometry.cbGeometryBuffer = 0;
                geometry.Reserved2        = 0;
            }

            return(geometry);
        }
        /// <summary>
        /// Decode this PDU from the PduMarshaler.
        /// </summary>
        /// <param name="marshaler">This is used to decode the fields of this PDU.</param>
        public override bool Decode(PduMarshaler marshaler)
        {
            try
            {
                this.cbGeometryData   = marshaler.ReadUInt32();
                this.Version          = (RdpegtVersionValues)marshaler.ReadUInt32();
                this.MappingId        = marshaler.ReadUInt64();
                this.UpdateType       = (UpdateTypeValues)marshaler.ReadUInt32();
                this.Flags            = marshaler.ReadUInt32();
                this.TopLevelId       = marshaler.ReadUInt64();
                this.Left             = marshaler.ReadUInt32();
                this.Top              = marshaler.ReadUInt32();
                this.Right            = marshaler.ReadUInt32();
                this.Bottom           = marshaler.ReadUInt32();
                this.TopLevelLeft     = marshaler.ReadUInt32();
                this.TopLevelTop      = marshaler.ReadUInt32();
                this.TopLevelRight    = marshaler.ReadUInt32();
                this.TopLevelBottom   = marshaler.ReadUInt32();
                this.GeometryType     = (GeometryTypeValues)marshaler.ReadUInt32();
                this.cbGeometryBuffer = marshaler.ReadUInt32();

                //Decode RGNDATA
                this.pGeometryBuffer.rdh.dwSize   = marshaler.ReadUInt32();
                this.pGeometryBuffer.rdh.iType    = marshaler.ReadUInt32();
                this.pGeometryBuffer.rdh.nCount   = marshaler.ReadUInt32();
                this.pGeometryBuffer.rdh.nRgnSize = marshaler.ReadUInt32();
                DecodeRect(marshaler, out this.pGeometryBuffer.rdh.rcBound);

                this.pGeometryBuffer.Buffer = new RECT[this.pGeometryBuffer.rdh.nCount];
                for (int i = 0; i < this.pGeometryBuffer.Buffer.Length; i++)
                {
                    DecodeRect(marshaler, out this.pGeometryBuffer.Buffer[i]);
                }

                this.Reserved2 = marshaler.ReadByte();

                return(true);
            }
            catch
            {
                marshaler.Reset();
                throw new PDUDecodeException(this.GetType(), marshaler.ReadToEnd());
            }
        }
        /// <summary>
        /// Send a MAPPED_GEOMETRY_PACKET to client to create a geometry mapping to a rect.
        /// </summary>
        /// <param name="mappingId">The id for the geometry mapping.</param>
        /// <param name="updateType">The update type.</param>
        /// <param name="left">The position to left bound.</param>
        /// <param name="top">The position to right bound.</param>
        /// <param name="width">The width of the rect.</param>
        /// <param name="height">The height of the rect.</param>
        public void SendMappedGeometryPacket(UInt64 mappingId, UpdateTypeValues updateType, uint left, uint top, uint width, uint height)
        {
            MAPPED_GEOMETRY_PACKET geometry = rdpegtServer.CreateMappedGeometryPacket(mappingId, updateType, left, top, width, height);

            rdpegtServer.SendRdpegtPdu(geometry);
        }
 /// <summary>
 /// Send a MAPPED_GEOMETRY_PACKET to client to create a geometry mapping to a rect.
 /// </summary>
 /// <param name="mappingId">The id for the geometry mapping.</param>
 /// <param name="updateType">The update type.</param>
 /// <param name="left">The position to left bound.</param>
 /// <param name="top">The position to right bound.</param>
 /// <param name="width">The width of the rect.</param>
 /// <param name="height">The height of the rect.</param>
 public void SendMappedGeometryPacket(UInt64 mappingId, UpdateTypeValues updateType, uint left, uint top, uint width, uint height)
 {
     MAPPED_GEOMETRY_PACKET geometry = rdpegtServer.CreateMappedGeometryPacket(mappingId, updateType, left, top, width, height);
     rdpegtServer.SendRdpegtPdu(geometry);
 }
        /// <summary>
        /// Decode this PDU from the PduMarshaler.
        /// </summary>
        /// <param name="marshaler">This is used to decode the fields of this PDU.</param>
        public override bool Decode(PduMarshaler marshaler)
        {
            try
            {
                this.cbGeometryData = marshaler.ReadUInt32();
                this.Version = (RdpegtVersionValues)marshaler.ReadUInt32();
                this.MappingId = marshaler.ReadUInt64();
                this.UpdateType = (UpdateTypeValues)marshaler.ReadUInt32();
                this.Flags = marshaler.ReadUInt32();
                this.TopLevelId = marshaler.ReadUInt64();
                this.Left = marshaler.ReadUInt32();
                this.Top = marshaler.ReadUInt32();
                this.Right = marshaler.ReadUInt32();
                this.Bottom = marshaler.ReadUInt32();
                this.TopLevelLeft = marshaler.ReadUInt32();
                this.TopLevelTop = marshaler.ReadUInt32();
                this.TopLevelRight = marshaler.ReadUInt32();
                this.TopLevelBottom = marshaler.ReadUInt32();
                this.GeometryType = (GeometryTypeValues)marshaler.ReadUInt32();
                this.cbGeometryBuffer = marshaler.ReadUInt32();

                //Decode RGNDATA
                this.pGeometryBuffer.rdh.dwSize = marshaler.ReadUInt32();
                this.pGeometryBuffer.rdh.iType = marshaler.ReadUInt32();
                this.pGeometryBuffer.rdh.nCount = marshaler.ReadUInt32();
                this.pGeometryBuffer.rdh.nRgnSize = marshaler.ReadUInt32();
                DecodeRect(marshaler, out this.pGeometryBuffer.rdh.rcBound);

                this.pGeometryBuffer.Buffer = new RECT[this.pGeometryBuffer.rdh.nCount];
                for (int i = 0; i < this.pGeometryBuffer.Buffer.Length; i++)
                {
                    DecodeRect(marshaler, out this.pGeometryBuffer.Buffer[i]);
                }

                this.Reserved2 = marshaler.ReadByte();

                return true;
            }
            catch
            {
                marshaler.Reset();
                throw new PDUDecodeException(this.GetType(), marshaler.ReadToEnd());
            }
        }