rdpgfx: more minor changes
authorzihao.jiang <zihao.jiang@yahoo.com>
Thu, 26 May 2016 18:11:52 +0000 (02:11 +0800)
committerzihao.jiang <zihao.jiang@yahoo.com>
Sun, 7 Aug 2016 12:15:39 +0000 (20:15 +0800)
1. Fix style for channels/rdpgfx/server/rdpgfx_main.c according to scripts/format_code.sh
2. Refactor and introduce APIs to allow rdpgfx server channel running in existing thread (similar to rdpsnd)

channels/rdpgfx/server/rdpgfx_main.c
channels/rdpgfx/server/rdpgfx_main.h
include/freerdp/server/rdpgfx.h

index 547b417..fbcf56b 100644 (file)
@@ -54,15 +54,14 @@ static INLINE UINT32 rdpgfx_pdu_length(UINT32 dataLen)
        return RDPGFX_HEADER_SIZE + dataLen;
 }
 
-static INLINE UINT rdpgfx_server_packet_init_header(wStream* s, UINT16 cmdId, UINT32 pduLength)
+static INLINE UINT rdpgfx_server_packet_init_header(wStream* s,
+               UINT16 cmdId, UINT32 pduLength)
 {
        RDPGFX_HEADER header;
-
        header.flags = 0;
        header.cmdId = cmdId;
        header.pduLength = pduLength;
-
-       /* Write header. Note that actual length might be changed 
+       /* Write header. Note that actual length might be changed
         * after the entire packet has been constructed. */
        return rdpgfx_write_header(s, &header);
 }
@@ -77,7 +76,6 @@ static INLINE UINT rdpgfx_server_packet_init_header(wStream* s, UINT16 cmdId, UI
 static INLINE void rdpgfx_server_packet_complete_header(wStream* s, size_t start)
 {
        size_t current = Stream_GetPosition(s);
-       
        /* Fill actual length */
        Stream_SetPosition(s, start + RDPGFX_HEADER_SIZE - sizeof(UINT32));
        Stream_Write_UINT32(s, current - start); /* pduLength (4 bytes) */
@@ -86,7 +84,7 @@ static INLINE void rdpgfx_server_packet_complete_header(wStream* s, size_t start
 
 /**
  * Function description
- * Send the stream for rdpgfx server packet. 
+ * Send the stream for rdpgfx server packet.
  * The packet would be compressed according to [MS-RDPEGFX].
  *
  * @return 0 on success, otherwise a Win32 error code
@@ -99,30 +97,30 @@ static UINT rdpgfx_server_packet_send(RdpgfxServerContext* context, wStream* s)
        BYTE* pSrcData = Stream_Buffer(s);
        UINT32 SrcSize = Stream_GetPosition(s);
        wStream* fs;
-       
        /* Allocate new stream with enough capacity. Additional overhead is
         * descriptor (1 bytes) + segmentCount (2 bytes) + uncompressedSize (4 bytes)
         * + segmentCount * size (4 bytes) */
-       fs = Stream_New(NULL, SrcSize + 7 
-          + (SrcSize/ZGFX_SEGMENTED_MAXSIZE + 1) * 4);
+       fs = Stream_New(NULL, SrcSize + 7
+                                       + (SrcSize/ZGFX_SEGMENTED_MAXSIZE + 1) * 4);
 
-       if(!fs)
+       if (!fs)
        {
-           WLog_ERR(TAG, "Stream_New failed!");
+               WLog_ERR(TAG, "Stream_New failed!");
                error = CHANNEL_RC_NO_MEMORY;
-           goto out;
+               goto out;
        }
 
-       if (zgfx_compress_to_stream(context->priv->zgfx, fs, pSrcData, SrcSize, &flags) < 0)
+       if (zgfx_compress_to_stream(context->priv->zgfx, fs, pSrcData,
+                                                               SrcSize, &flags) < 0)
        {
                WLog_ERR(TAG, "zgfx_compress_to_stream failed!");
                error = ERROR_INTERNAL_ERROR;
                goto out;
        }
 
-       if (!WTSVirtualChannelWrite(context->priv->rdpgfx_channel, 
-                                   (PCHAR) Stream_Buffer(fs), 
-                                   Stream_GetPosition(fs), &written))
+       if (!WTSVirtualChannelWrite(context->priv->rdpgfx_channel,
+                                                               (PCHAR) Stream_Buffer(fs),
+                                                               Stream_GetPosition(fs), &written))
        {
                WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
                error = ERROR_INTERNAL_ERROR;
@@ -131,16 +129,14 @@ static UINT rdpgfx_server_packet_send(RdpgfxServerContext* context, wStream* s)
 
        if (written < Stream_GetPosition(fs))
        {
-               WLog_WARN(TAG, "Unexpected bytes written: %lu/%lu", 
-                         written, Stream_GetPosition(fs));
+               WLog_WARN(TAG, "Unexpected bytes written: %lu/%lu",
+                                 written, Stream_GetPosition(fs));
        }
 
        error = CHANNEL_RC_OK;
-
 out:
        Stream_Free(fs, TRUE);
        Stream_Free(s, TRUE);
-
        return error;
 }
 
@@ -148,10 +144,10 @@ out:
  * Function description
  * Create new stream for single rdpgfx packet. The new stream length
  * would be required data length + header. The header will be written
- * to the stream before return, but the pduLength field might be 
+ * to the stream before return, but the pduLength field might be
  * changed in rdpgfx_server_single_packet_send.
  *
- * @param cmdId 
+ * @param cmdId
  * @param dataLen estimated data length without header
  *
  * @return new stream
@@ -160,43 +156,40 @@ static wStream* rdpgfx_server_single_packet_new(UINT16 cmdId, UINT32 dataLen)
 {
        UINT error;
        wStream* s;
-       UINT32 pduLength = rdpgfx_pdu_length(dataLen); 
-
+       UINT32 pduLength = rdpgfx_pdu_length(dataLen);
        s = Stream_New(NULL, pduLength);
 
-       if(!s)
+       if (!s)
        {
-           WLog_ERR(TAG, "Stream_New failed!");
-           goto error;
+               WLog_ERR(TAG, "Stream_New failed!");
+               goto error;
        }
 
        if ((error = rdpgfx_server_packet_init_header(s, cmdId, pduLength)))
        {
                WLog_ERR(TAG, "Failed to init header with error %lu!", error);
-           goto error;
+               goto error;
        }
 
        return s;
-
 error:
        Stream_Free(s, TRUE);
-
        return NULL;
 }
 
 /**
  * Function description
- * Send the stream for single rdpgfx packet. 
+ * Send the stream for single rdpgfx packet.
  * The header will be filled with actual length.
  * The packet would be compressed according to [MS-RDPEGFX].
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static INLINE UINT rdpgfx_server_single_packet_send(RdpgfxServerContext* context, wStream* s)
+static INLINE UINT rdpgfx_server_single_packet_send(
+       RdpgfxServerContext* context, wStream* s)
 {
        /* Fill actual length */
        rdpgfx_server_packet_complete_header(s, 0);
-       
        return rdpgfx_server_packet_send(context, s);
 }
 
@@ -205,12 +198,13 @@ static INLINE UINT rdpgfx_server_single_packet_send(RdpgfxServerContext* context
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, RDPGFX_CAPS_CONFIRM_PDU* capsConfirm)
+static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context,
+               RDPGFX_CAPS_CONFIRM_PDU* capsConfirm)
 {
        RDPGFX_CAPSET* capsSet = capsConfirm->capsSet;
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_CAPSCONFIRM, 
-                    sizeof(RDPGFX_CAPSET) + sizeof(capsSet->flags));
+                                        RDPGFX_CMDID_CAPSCONFIRM,
+                                        sizeof(RDPGFX_CAPSET) + sizeof(capsSet->flags));
 
        if (!s)
        {
@@ -221,7 +215,6 @@ static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, RDPGFX_CA
        Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */
        Stream_Write_UINT32(s, sizeof(capsSet->flags)); /* capsDataLength (4 bytes) */
        Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -230,23 +223,24 @@ static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, RDPGFX_CA
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, RDPGFX_RESET_GRAPHICS_PDU* pdu)
+static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context,
+               RDPGFX_RESET_GRAPHICS_PDU* pdu)
 {
        UINT32 index;
        MONITOR_DEF* monitor;
        wStream* s;
-       
+
        /* Check monitorCount. This ensures total size within 340 bytes) */
        if (pdu->monitorCount >= 16)
        {
                WLog_ERR(TAG, "Monitor count MUST be less than or equal to 16: %lu",
-                        pdu->monitorCount);
+                                pdu->monitorCount);
                return ERROR_INVALID_DATA;
        }
 
        s = rdpgfx_server_single_packet_new(
-               RDPGFX_CMDID_RESETGRAPHICS,
-               RDPGFX_RESET_GRAPHICS_PDU_SIZE - RDPGFX_HEADER_SIZE);
+                       RDPGFX_CMDID_RESETGRAPHICS,
+                       RDPGFX_RESET_GRAPHICS_PDU_SIZE - RDPGFX_HEADER_SIZE);
 
        if (!s)
        {
@@ -270,7 +264,6 @@ static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, RDPGFX_
 
        /* pad (total size must be 340 bytes) */
        Stream_SetPosition(s, RDPGFX_RESET_GRAPHICS_PDU_SIZE);
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -279,11 +272,12 @@ static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, RDPGFX_
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* pdu)
+static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context,
+               RDPGFX_EVICT_CACHE_ENTRY_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_EVICTCACHEENTRY, 
-                    sizeof(RDPGFX_EVICT_CACHE_ENTRY_PDU));
+                                        RDPGFX_CMDID_EVICTCACHEENTRY,
+                                        sizeof(RDPGFX_EVICT_CACHE_ENTRY_PDU));
 
        if (!s)
        {
@@ -292,7 +286,6 @@ static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, RDPG
        }
 
        Stream_Write_UINT16(s, pdu->cacheSlot); /* cacheSlot (2 bytes) */
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -301,12 +294,14 @@ static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, RDPG
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* pdu)
+static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context,
+               RDPGFX_CACHE_IMPORT_REPLY_PDU* pdu)
 {
        UINT16 index;
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_CACHEIMPORTREPLY, 
-                    sizeof(RDPGFX_CACHE_IMPORT_REPLY_PDU) + sizeof(UINT16) * pdu->importedEntriesCount);
+                                        RDPGFX_CMDID_CACHEIMPORTREPLY,
+                                        sizeof(RDPGFX_CACHE_IMPORT_REPLY_PDU) +
+                                        sizeof(UINT16) * pdu->importedEntriesCount);
 
        if (!s)
        {
@@ -314,7 +309,9 @@ static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, RDP
                return CHANNEL_RC_NO_MEMORY;
        }
 
-       Stream_Write_UINT16(s, pdu->importedEntriesCount); /* importedEntriesCount (2 bytes) */
+       /* importedEntriesCount (2 bytes) */
+       Stream_Write_UINT16(s, pdu->importedEntriesCount);
+
        for (index = 0; index < pdu->importedEntriesCount; index++)
        {
                Stream_Write_UINT16(s, pdu->cacheSlots[index]); /* cacheSlot (2 bytes) */
@@ -328,11 +325,12 @@ static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, RDP
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, RDPGFX_CREATE_SURFACE_PDU* pdu)
+static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context,
+               RDPGFX_CREATE_SURFACE_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_CREATESURFACE, 
-                    sizeof(RDPGFX_CREATE_SURFACE_PDU));
+                                        RDPGFX_CMDID_CREATESURFACE,
+                                        sizeof(RDPGFX_CREATE_SURFACE_PDU));
 
        if (!s)
        {
@@ -344,7 +342,6 @@ static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, RDPGFX_
        Stream_Write_UINT16(s, pdu->width); /* width (2 bytes) */
        Stream_Write_UINT16(s, pdu->height); /* height (2 bytes) */
        Stream_Write_UINT8(s, pdu->pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -353,11 +350,12 @@ static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, RDPGFX_
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-UINT rdpgfx_send_delete_surface_pdu(RdpgfxServerContext* context, RDPGFX_DELETE_SURFACE_PDU* pdu)
+UINT rdpgfx_send_delete_surface_pdu(RdpgfxServerContext* context,
+                                                                       RDPGFX_DELETE_SURFACE_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_DELETESURFACE, 
-                    sizeof(RDPGFX_DELETE_SURFACE_PDU));
+                                        RDPGFX_CMDID_DELETESURFACE,
+                                        sizeof(RDPGFX_DELETE_SURFACE_PDU));
 
        if (!s)
        {
@@ -366,17 +364,18 @@ UINT rdpgfx_send_delete_surface_pdu(RdpgfxServerContext* context, RDPGFX_DELETE_
        }
 
        Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
-static INLINE void rdpgfx_write_start_frame_pdu(wStream* s, RDPGFX_START_FRAME_PDU* pdu)
+static INLINE void rdpgfx_write_start_frame_pdu(wStream* s,
+               RDPGFX_START_FRAME_PDU* pdu)
 {
        Stream_Write_UINT32(s, pdu->timestamp); /* timestamp (4 bytes) */
        Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */
 }
 
-static INLINE void rdpgfx_write_end_frame_pdu(wStream* s, RDPGFX_END_FRAME_PDU* pdu)
+static INLINE void rdpgfx_write_end_frame_pdu(wStream* s,
+               RDPGFX_END_FRAME_PDU* pdu)
 {
        Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */
 }
@@ -386,11 +385,12 @@ static INLINE void rdpgfx_write_end_frame_pdu(wStream* s, RDPGFX_END_FRAME_PDU*
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, RDPGFX_START_FRAME_PDU* pdu)
+static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context,
+                                                                               RDPGFX_START_FRAME_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_STARTFRAME, 
-                    sizeof(RDPGFX_START_FRAME_PDU));
+                                        RDPGFX_CMDID_STARTFRAME,
+                                        sizeof(RDPGFX_START_FRAME_PDU));
 
        if (!s)
        {
@@ -399,7 +399,6 @@ static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, RDPGFX_STA
        }
 
        rdpgfx_write_start_frame_pdu(s, pdu);
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -408,11 +407,12 @@ static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, RDPGFX_STA
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_end_frame_pdu(RdpgfxServerContext* context, RDPGFX_END_FRAME_PDU* pdu)
+static UINT rdpgfx_send_end_frame_pdu(RdpgfxServerContext* context,
+                                                                         RDPGFX_END_FRAME_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_ENDFRAME, 
-                    sizeof(RDPGFX_END_FRAME_PDU));
+                                        RDPGFX_CMDID_ENDFRAME,
+                                        sizeof(RDPGFX_END_FRAME_PDU));
 
        if (!s)
        {
@@ -421,22 +421,22 @@ static UINT rdpgfx_send_end_frame_pdu(RdpgfxServerContext* context, RDPGFX_END_F
        }
 
        rdpgfx_write_end_frame_pdu(s, pdu);
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
 /**
  * Function description
- * Estimate RFX_AVC420_BITMAP_STREAM structure size in stream 
+ * Estimate RFX_AVC420_BITMAP_STREAM structure size in stream
  *
  * @return estimated size
  */
-static INLINE UINT32 rdpgfx_estimate_h264_avc420(RDPGFX_AVC420_BITMAP_STREAM *havc420)
+static INLINE UINT32 rdpgfx_estimate_h264_avc420(
+       RDPGFX_AVC420_BITMAP_STREAM* havc420)
 {
        return sizeof(UINT32) /* numRegionRects */
-            + (sizeof(RECTANGLE_16) + 2) /* regionRects + quantQualityVals */
-            * havc420->meta.numRegionRects
-            + havc420->length;
+                  + (sizeof(RECTANGLE_16) + 2) /* regionRects + quantQualityVals */
+                  * havc420->meta.numRegionRects
+                  + havc420->length;
 }
 
 /**
@@ -447,28 +447,26 @@ static INLINE UINT32 rdpgfx_estimate_h264_avc420(RDPGFX_AVC420_BITMAP_STREAM *ha
  */
 static INLINE UINT32 rdpgfx_estimate_surface_command(RDPGFX_SURFACE_COMMAND* cmd)
 {
-       RDPGFX_AVC420_BITMAP_STREAM *havc420 = NULL;
-       RDPGFX_AVC444_BITMAP_STREAM *havc444 = NULL;
+       RDPGFX_AVC420_BITMAP_STREAMhavc420 = NULL;
+       RDPGFX_AVC444_BITMAP_STREAMhavc444 = NULL;
        UINT32 h264Size = 0;
 
        /* Create new stream according to codec. */
        if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE ||
-               cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2)
+                       cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2)
        {
                return sizeof(RDPGFX_WIRE_TO_SURFACE_PDU_2) + cmd->length;
        }
        else if (cmd->codecId == RDPGFX_CODECID_AVC420)
        {
-               havc420 = (RDPGFX_AVC420_BITMAP_STREAM *)cmd->extra;
+               havc420 = (RDPGFX_AVC420_BITMAP_STREAM*)cmd->extra;
                h264Size = rdpgfx_estimate_h264_avc420(havc420);
-
                return sizeof(RDPGFX_WIRE_TO_SURFACE_PDU_1) + h264Size;
        }
        else if (cmd->codecId == RDPGFX_CODECID_AVC444)
        {
-               havc444 = (RDPGFX_AVC444_BITMAP_STREAM *)cmd->extra;
+               havc444 = (RDPGFX_AVC444_BITMAP_STREAM*)cmd->extra;
                h264Size = sizeof(UINT32); /* cbAvc420EncodedBitstream1 */
-
                /* avc420EncodedBitstream1 */
                havc420 = &(havc444->bitstream[0]);
                h264Size += rdpgfx_estimate_h264_avc420(havc420);
@@ -490,7 +488,7 @@ static INLINE UINT32 rdpgfx_estimate_surface_command(RDPGFX_SURFACE_COMMAND* cmd
 
 /**
  * Function description
- * Resolve RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 
+ * Resolve RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2
  * according to codecId
  *
  * @return 0 on success, otherwise a Win32 error code
@@ -498,7 +496,7 @@ static INLINE UINT32 rdpgfx_estimate_surface_command(RDPGFX_SURFACE_COMMAND* cmd
 static INLINE UINT16 rdpgfx_surface_command_cmdid(RDPGFX_SURFACE_COMMAND* cmd)
 {
        if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE ||
-               cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2)
+                       cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2)
        {
                return RDPGFX_CMDID_WIRETOSURFACE_2;
        }
@@ -517,12 +515,12 @@ static UINT rdpgfx_write_h264_metablock(wStream* s, RDPGFX_H264_METABLOCK* meta)
        RECTANGLE_16* regionRect;
        RDPGFX_H264_QUANT_QUALITY* quantQualityVal;
        UINT error = CHANNEL_RC_OK;
-
        Stream_Write_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */
 
        for (index = 0; index < meta->numRegionRects; index++)
        {
                regionRect = &(meta->regionRects[index]);
+
                if ((error = rdpgfx_write_rect16(s, regionRect)))
                {
                        WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error);
@@ -533,11 +531,11 @@ static UINT rdpgfx_write_h264_metablock(wStream* s, RDPGFX_H264_METABLOCK* meta)
        for (index = 0; index < meta->numRegionRects; index++)
        {
                quantQualityVal = &(meta->quantQualityVals[index]);
-
                Stream_Write_UINT8(s, quantQualityVal->qp
-                                  | (quantQualityVal->r << 6)
-                                  | (quantQualityVal->p << 7)); /* qpVal (1 byte) */
-               Stream_Write_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */
+                                                  | (quantQualityVal->r << 6)
+                                                  | (quantQualityVal->p << 7)); /* qpVal (1 byte) */
+               /* qualityVal (1 byte) */
+               Stream_Write_UINT8(s, quantQualityVal->qualityVal);
        }
 
        return error;
@@ -549,12 +547,15 @@ static UINT rdpgfx_write_h264_metablock(wStream* s, RDPGFX_H264_METABLOCK* meta)
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static INLINE UINT rdpgfx_write_h264_avc420(wStream* s, RDPGFX_AVC420_BITMAP_STREAM* havc420)
+static INLINE UINT rdpgfx_write_h264_avc420(wStream* s,
+               RDPGFX_AVC420_BITMAP_STREAM* havc420)
 {
        UINT error = CHANNEL_RC_OK;
+
        if ((error = rdpgfx_write_h264_metablock(s, &(havc420->meta))))
        {
-               WLog_ERR(TAG, "rdpgfx_write_h264_metablock failed with error %lu!", error);
+               WLog_ERR(TAG, "rdpgfx_write_h264_metablock failed with error %lu!",
+                                error);
                return error;
        }
 
@@ -572,44 +573,40 @@ static INLINE UINT rdpgfx_write_h264_avc420(wStream* s, RDPGFX_AVC420_BITMAP_STR
 static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd)
 {
        UINT error = CHANNEL_RC_OK;
-       RDPGFX_AVC420_BITMAP_STREAM *havc420 = NULL;
-       RDPGFX_AVC444_BITMAP_STREAM *havc444 = NULL;
+       RDPGFX_AVC420_BITMAP_STREAMhavc420 = NULL;
+       RDPGFX_AVC444_BITMAP_STREAMhavc444 = NULL;
        UINT32 bitmapDataStart = 0;
        UINT32 bitmapDataLength = 0;
 
        if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE ||
-           cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2)
+                       cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2)
        {
                /* Write RDPGFX_CMDID_WIRETOSURFACE_2 format for CAPROGRESSIVE */
-
                Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */
                Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */
                Stream_Write_UINT32(s, cmd->contextId); /* codecContextId (4 bytes) */
                Stream_Write_UINT8(s, cmd->format); /* pixelFormat (1 byte) */
-
                Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */
                Stream_Write(s, cmd->data, cmd->length);
        }
        else
        {
                /* Write RDPGFX_CMDID_WIRETOSURFACE_1 format for others */
-
                Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */
                Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */
                Stream_Write_UINT8(s, cmd->format); /* pixelFormat (1 byte) */
-
                Stream_Write_UINT16(s, cmd->left); /* left (2 bytes) */
                Stream_Write_UINT16(s, cmd->top); /* top (2 bytes) */
                Stream_Write_UINT16(s, cmd->right); /* right (2 bytes) */
                Stream_Write_UINT16(s, cmd->bottom); /* bottom (2 bytes) */
-
                Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */
                bitmapDataStart = Stream_GetPosition(s);
 
                if (cmd->codecId == RDPGFX_CODECID_AVC420)
                {
-                       havc420 = (RDPGFX_AVC420_BITMAP_STREAM *)cmd->extra;
+                       havc420 = (RDPGFX_AVC420_BITMAP_STREAM*)cmd->extra;
                        error = rdpgfx_write_h264_avc420(s, havc420);
+
                        if (error != CHANNEL_RC_OK)
                        {
                                WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!");
@@ -618,14 +615,13 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd
                }
                else if (cmd->codecId == RDPGFX_CODECID_AVC444)
                {
-                       havc444 = (RDPGFX_AVC444_BITMAP_STREAM *)cmd->extra;
+                       havc444 = (RDPGFX_AVC444_BITMAP_STREAM*)cmd->extra;
                        havc420 = &(havc444->bitstream[0]);
-
                        /* avc420EncodedBitstreamInfo (4 bytes) */
                        Stream_Write_UINT32(s, havc420->length | (havc444->LC << 30UL));
-
                        /* avc420EncodedBitstream1 */
                        error = rdpgfx_write_h264_avc420(s, havc420);
+
                        if (error != CHANNEL_RC_OK)
                        {
                                WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!");
@@ -637,6 +633,7 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd
                        {
                                havc420 = &(havc444->bitstream[0]);
                                error = rdpgfx_write_h264_avc420(s, havc420);
+
                                if (error != CHANNEL_RC_OK)
                                {
                                        WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!");
@@ -650,7 +647,6 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd
                }
 
                assert(Stream_GetPosition(s) <= Stream_Capacity(s));
-
                /* Fill actual bitmap data length */
                bitmapDataLength = Stream_GetPosition(s) - bitmapDataStart;
                Stream_SetPosition(s, bitmapDataStart - sizeof(UINT32));
@@ -663,19 +659,19 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd
 
 /**
  * Function description
- * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 
+ * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2
  * message according to codecId
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd)
+static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context,
+                                                                               RDPGFX_SURFACE_COMMAND* cmd)
 {
        UINT error = CHANNEL_RC_OK;
        wStream* s;
-
        s = rdpgfx_server_single_packet_new(
-           rdpgfx_surface_command_cmdid(cmd), 
-           rdpgfx_estimate_surface_command(cmd));
+                       rdpgfx_surface_command_cmdid(cmd),
+                       rdpgfx_estimate_surface_command(cmd));
 
        if (!s)
        {
@@ -684,6 +680,7 @@ static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, RDPGFX_SUR
        }
 
        error = rdpgfx_write_surface_command(s, cmd);
+
        if (error != CHANNEL_RC_OK)
        {
                WLog_ERR(TAG, "rdpgfx_write_surface_command failed!");
@@ -691,24 +688,22 @@ static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, RDPGFX_SUR
        }
 
        return rdpgfx_server_single_packet_send(context, s);
-
 error:
        Stream_Free(s, TRUE);
-
        return error;
 }
 
 /**
  * Function description
- * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 
+ * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2
  * message according to codecId.
  * Prepend/append start/end frame message in same packet if exists.
  *
  * @return 0 on success, otherwise a Win32 error code
  */
 static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context,
-            RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, 
-            RDPGFX_END_FRAME_PDU* endFrame)
+               RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame,
+               RDPGFX_END_FRAME_PDU* endFrame)
 
 {
        UINT error = CHANNEL_RC_OK;
@@ -728,9 +723,9 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context,
 
        s = Stream_New(NULL, size);
 
-       if(!s)
+       if (!s)
        {
-           WLog_ERR(TAG, "Stream_New failed!");
+               WLog_ERR(TAG, "Stream_New failed!");
                return CHANNEL_RC_NO_MEMORY;
        }
 
@@ -738,8 +733,9 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context,
        if (startFrame)
        {
                position = Stream_GetPosition(s);
-               error = rdpgfx_server_packet_init_header(s, 
-                       RDPGFX_CMDID_STARTFRAME, 0);
+               error = rdpgfx_server_packet_init_header(s,
+                               RDPGFX_CMDID_STARTFRAME, 0);
+
                if (error != CHANNEL_RC_OK)
                {
                        WLog_ERR(TAG, "Failed to init header with error %lu!", error);
@@ -752,9 +748,10 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context,
 
        /* Write RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 */
        position = Stream_GetPosition(s);
-       error = rdpgfx_server_packet_init_header(s, 
-               rdpgfx_surface_command_cmdid(cmd), 
-               0); // Actual length will be filled later
+       error = rdpgfx_server_packet_init_header(s,
+                       rdpgfx_surface_command_cmdid(cmd),
+                       0); // Actual length will be filled later
+
        if (error != CHANNEL_RC_OK)
        {
                WLog_ERR(TAG, "Failed to init header with error %lu!", error);
@@ -762,19 +759,22 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context,
        }
 
        error = rdpgfx_write_surface_command(s, cmd);
+
        if (error != CHANNEL_RC_OK)
        {
                WLog_ERR(TAG, "rdpgfx_write_surface_command failed!");
                goto error;
        }
+
        rdpgfx_server_packet_complete_header(s, position);
 
        /* Write end frame if exists */
        if (endFrame)
        {
                position = Stream_GetPosition(s);
-               error = rdpgfx_server_packet_init_header(s, 
-                       RDPGFX_CMDID_ENDFRAME, 0);
+               error = rdpgfx_server_packet_init_header(s,
+                               RDPGFX_CMDID_ENDFRAME, 0);
+
                if (error != CHANNEL_RC_OK)
                {
                        WLog_ERR(TAG, "Failed to init header with error %lu!", error);
@@ -786,10 +786,8 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context,
        }
 
        return rdpgfx_server_packet_send(context, s);
-
 error:
        Stream_Free(s, TRUE);
-
        return error;
 }
 
@@ -798,11 +796,12 @@ error:
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* pdu)
+static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context,
+               RDPGFX_DELETE_ENCODING_CONTEXT_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_DELETEENCODINGCONTEXT, 
-                    sizeof(RDPGFX_DELETE_ENCODING_CONTEXT_PDU));
+                                        RDPGFX_CMDID_DELETEENCODINGCONTEXT,
+                                        sizeof(RDPGFX_DELETE_ENCODING_CONTEXT_PDU));
 
        if (!s)
        {
@@ -812,7 +811,6 @@ static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context
 
        Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */
        Stream_Write_UINT32(s, pdu->codecContextId); /* codecContextId (4 bytes) */
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -821,14 +819,16 @@ static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_PDU* pdu)
+UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context,
+                                                               RDPGFX_SOLID_FILL_PDU* pdu)
 {
        UINT error = CHANNEL_RC_OK;
        UINT16 index;
        RECTANGLE_16* fillRect;
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_SOLIDFILL, 
-                    sizeof(RDPGFX_SOLID_FILL_PDU) + sizeof(RECTANGLE_16) * pdu->fillRectCount);
+                                        RDPGFX_CMDID_SOLIDFILL,
+                                        sizeof(RDPGFX_SOLID_FILL_PDU) +
+                                        sizeof(RECTANGLE_16) * pdu->fillRectCount);
 
        if (!s)
        {
@@ -837,16 +837,20 @@ UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_
        }
 
        Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */
-       if ((error = rdpgfx_write_color32(s, &(pdu->fillPixel)))) /* fillPixel (4 bytes) */
+
+       /* fillPixel (4 bytes) */
+       if ((error = rdpgfx_write_color32(s, &(pdu->fillPixel))))
        {
                WLog_ERR(TAG, "rdpgfx_write_color32 failed with error %lu!", error);
                goto error;
        }
 
        Stream_Write_UINT16(s, pdu->fillRectCount); /* fillRectCount (2 bytes) */
+
        for (index = 0; index < pdu->fillRectCount; index++)
        {
                fillRect = &(pdu->fillRects[index]);
+
                if ((error = rdpgfx_write_rect16(s, fillRect)))
                {
                        WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error);
@@ -855,10 +859,8 @@ UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_
        }
 
        return rdpgfx_server_single_packet_send(context, s);
-
 error:
        Stream_Free(s, TRUE);
-
        return error;
 }
 
@@ -867,14 +869,16 @@ error:
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* pdu)
+static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context,
+               RDPGFX_SURFACE_TO_SURFACE_PDU* pdu)
 {
        UINT error = CHANNEL_RC_OK;
        UINT16 index;
        RDPGFX_POINT16* destPt;
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_SURFACETOSURFACE, 
-                    sizeof(RDPGFX_SURFACE_TO_SURFACE_PDU) + sizeof(RDPGFX_POINT16) * pdu->destPtsCount);
+                                        RDPGFX_CMDID_SURFACETOSURFACE,
+                                        sizeof(RDPGFX_SURFACE_TO_SURFACE_PDU) +
+                                        sizeof(RDPGFX_POINT16) * pdu->destPtsCount);
 
        if (!s)
        {
@@ -885,16 +889,19 @@ static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, RDP
        Stream_Write_UINT16(s, pdu->surfaceIdSrc); /* surfaceIdSrc (2 bytes) */
        Stream_Write_UINT16(s, pdu->surfaceIdDest); /* surfaceIdDest (2 bytes) */
 
-       if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) /* rectSrc (8 bytes ) */
+       /* rectSrc (8 bytes ) */
+       if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc))))
        {
                WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error);
                goto error;
        }
 
        Stream_Write_UINT16(s, pdu->destPtsCount); /* destPtsCount (2 bytes) */
+
        for (index = 0; index < pdu->destPtsCount; index++)
        {
                destPt = &(pdu->destPts[index]);
+
                if ((error = rdpgfx_write_point16(s, destPt)))
                {
                        WLog_ERR(TAG, "rdpgfx_write_point16 failed with error %lu!", error);
@@ -903,10 +910,8 @@ static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, RDP
        }
 
        return rdpgfx_server_single_packet_send(context, s);
-
 error:
        Stream_Free(s, TRUE);
-
        return error;
 }
 
@@ -915,12 +920,13 @@ error:
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_surface_to_cache_pdu(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* pdu)
+static UINT rdpgfx_send_surface_to_cache_pdu(RdpgfxServerContext* context,
+               RDPGFX_SURFACE_TO_CACHE_PDU* pdu)
 {
        UINT error = CHANNEL_RC_OK;
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_SURFACETOCACHE, 
-                    sizeof(RDPGFX_SURFACE_TO_CACHE_PDU));
+                                        RDPGFX_CMDID_SURFACETOCACHE,
+                                        sizeof(RDPGFX_SURFACE_TO_CACHE_PDU));
 
        if (!s)
        {
@@ -931,17 +937,17 @@ static UINT rdpgfx_send_surface_to_cache_pdu(RdpgfxServerContext* context, RDPGF
        Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */
        Stream_Write_UINT64(s, pdu->cacheKey); /* cacheKey (8 bytes) */
        Stream_Write_UINT16(s, pdu->cacheSlot); /* cacheSlot (2 bytes) */
-       if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) /* rectSrc (8 bytes ) */
+
+       /* rectSrc (8 bytes ) */
+       if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc))))
        {
                WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error);
                goto error;
        }
 
        return rdpgfx_server_single_packet_send(context, s);
-
 error:
        Stream_Free(s, TRUE);
-
        return error;
 }
 
@@ -950,14 +956,16 @@ error:
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* pdu)
+static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context,
+               RDPGFX_CACHE_TO_SURFACE_PDU* pdu)
 {
        UINT error = CHANNEL_RC_OK;
        UINT16 index;
        RDPGFX_POINT16* destPt;
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_CACHETOSURFACE, 
-                    sizeof(RDPGFX_CACHE_TO_SURFACE_PDU) + sizeof(RDPGFX_POINT16) * pdu->destPtsCount);
+                                        RDPGFX_CMDID_CACHETOSURFACE,
+                                        sizeof(RDPGFX_CACHE_TO_SURFACE_PDU) +
+                                        sizeof(RDPGFX_POINT16) * pdu->destPtsCount);
 
        if (!s)
        {
@@ -972,6 +980,7 @@ static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, RDPGF
        for (index = 0; index < pdu->destPtsCount; index++)
        {
                destPt = &(pdu->destPts[index]);
+
                if ((error = rdpgfx_write_point16(s, destPt)))
                {
                        WLog_ERR(TAG, "rdpgfx_write_point16 failed with error %lu", error);
@@ -980,10 +989,8 @@ static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, RDPGF
        }
 
        return rdpgfx_server_single_packet_send(context, s);
-
 error:
        Stream_Free(s, TRUE);
-
        return error;
 }
 
@@ -992,11 +999,12 @@ error:
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* pdu)
+static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context,
+               RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_MAPSURFACETOOUTPUT, 
-                    sizeof(RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU));
+                                        RDPGFX_CMDID_MAPSURFACETOOUTPUT,
+                                        sizeof(RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU));
 
        if (!s)
        {
@@ -1008,7 +1016,6 @@ static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context,
        Stream_Write_UINT16(s, 0); /* reserved (2 bytes). Must be 0 */
        Stream_Write_UINT32(s, pdu->outputOriginX); /* outputOriginX (4 bytes) */
        Stream_Write_UINT32(s, pdu->outputOriginY); /* outputOriginY (4 bytes) */
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -1017,11 +1024,12 @@ static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context,
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* pdu)
+static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context,
+               RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* pdu)
 {
        wStream* s = rdpgfx_server_single_packet_new(
-                    RDPGFX_CMDID_MAPSURFACETOWINDOW, 
-                    sizeof(RDPGFX_MAP_SURFACE_TO_WINDOW_PDU));
+                                        RDPGFX_CMDID_MAPSURFACETOWINDOW,
+                                        sizeof(RDPGFX_MAP_SURFACE_TO_WINDOW_PDU));
 
        if (!s)
        {
@@ -1033,7 +1041,6 @@ static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context,
        Stream_Write_UINT64(s, pdu->windowId); /* windowId (8 bytes) */
        Stream_Write_UINT32(s, pdu->mappedWidth); /* mappedWidth (4 bytes) */
        Stream_Write_UINT32(s, pdu->mappedHeight); /* mappedHeight (4 bytes) */
-
        return rdpgfx_server_single_packet_send(context, s);
 }
 
@@ -1042,26 +1049,30 @@ static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context,
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context, wStream* s)
+static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context,
+               wStream* s)
 {
        RDPGFX_FRAME_ACKNOWLEDGE_PDU pdu;
        UINT error = CHANNEL_RC_OK;
 
-    if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_FRAME_ACKNOWLEDGE_PDU))
-    {
-        WLog_ERR(TAG, "not enough data!");
-        return ERROR_INVALID_DATA;
-    }
+       if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_FRAME_ACKNOWLEDGE_PDU))
+       {
+               WLog_ERR(TAG, "not enough data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT32(s, pdu.queueDepth); /* queueDepth (4 bytes) */
        Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */
-       Stream_Read_UINT32(s, pdu.totalFramesDecoded); /* totalFramesDecoded (4 bytes) */
+       /* totalFramesDecoded (4 bytes) */
+       Stream_Read_UINT32(s, pdu.totalFramesDecoded);
 
        if (context)
        {
                IFCALLRET(context->FrameAcknowledge, error, context, &pdu);
+
                if (error)
-                       WLog_ERR(TAG, "context->FrameAcknowledge failed with error %lu", error);
+                       WLog_ERR(TAG, "context->FrameAcknowledge failed with error %lu",
+                                        error);
        }
 
        return error;
@@ -1072,20 +1083,23 @@ static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context, wStr
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wStream* s)
+static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context,
+               wStream* s)
 {
        UINT16 index;
        RDPGFX_CACHE_IMPORT_OFFER_PDU pdu;
        RDPGFX_CACHE_ENTRY_METADATA* cacheEntries;
        UINT error = CHANNEL_RC_OK;
 
-    if (Stream_GetRemainingLength(s) < sizeof(UINT16))
-    {
-        WLog_ERR(TAG, "not enough data!");
-        return ERROR_INVALID_DATA;
-    }
+       if (Stream_GetRemainingLength(s) < sizeof(UINT16))
+       {
+               WLog_ERR(TAG, "not enough data!");
+               return ERROR_INVALID_DATA;
+       }
+
+       /* cacheEntriesCount (2 bytes) */
+       Stream_Read_UINT16(s, pdu.cacheEntriesCount);
 
-       Stream_Read_UINT16(s, pdu.cacheEntriesCount); /* cacheEntriesCount (2 bytes) */
        if (pdu.cacheEntriesCount <= 0)
        {
                /* According to the latest spec, capsSetCount <= 3 */
@@ -1093,16 +1107,16 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt
                return ERROR_INVALID_DATA;
        }
 
-    if (Stream_GetRemainingLength(s) < 
-          (pdu.cacheEntriesCount * sizeof(RDPGFX_CACHE_ENTRY_METADATA)))
-    {
-        WLog_ERR(TAG, "not enough data!");
-        return ERROR_INVALID_DATA;
-    }
+       if (Stream_GetRemainingLength(s) <
+                       (pdu.cacheEntriesCount * sizeof(RDPGFX_CACHE_ENTRY_METADATA)))
+       {
+               WLog_ERR(TAG, "not enough data!");
+               return ERROR_INVALID_DATA;
+       }
 
-       pdu.cacheEntries = (RDPGFX_CACHE_ENTRY_METADATA*) 
-                          calloc(pdu.cacheEntriesCount,
-                          sizeof(RDPGFX_CACHE_ENTRY_METADATA));
+       pdu.cacheEntries = (RDPGFX_CACHE_ENTRY_METADATA*)
+                                          calloc(pdu.cacheEntriesCount,
+                                                         sizeof(RDPGFX_CACHE_ENTRY_METADATA));
 
        if (!pdu.cacheEntries)
        {
@@ -1114,18 +1128,20 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt
        {
                cacheEntries = &(pdu.cacheEntries[index]);
                Stream_Read_UINT64(s, cacheEntries->cacheKey); /* cacheKey (8 bytes) */
-               Stream_Read_UINT32(s, cacheEntries->bitmapLength); /* bitmapLength (4 bytes) */
+               /* bitmapLength (4 bytes) */
+               Stream_Read_UINT32(s, cacheEntries->bitmapLength);
        }
 
        if (context)
        {
                IFCALLRET(context->CacheImportOffer, error, context, &pdu);
+
                if (error)
-                       WLog_ERR(TAG, "context->CacheImportOffer failed with error %lu", error);
+                       WLog_ERR(TAG, "context->CacheImportOffer failed with error %lu",
+                                        error);
        }
 
        free(pdu.cacheEntries);
-
        return error;
 }
 
@@ -1134,7 +1150,8 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream* s)
+static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
+               wStream* s)
 {
        UINT16 index;
        RDPGFX_CAPSET* capsSet;
@@ -1143,13 +1160,14 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream
        UINT error = CHANNEL_RC_OK;
        UINT32 capsDataLength;
 
-    if (Stream_GetRemainingLength(s) < sizeof(UINT16))
-    {
-        WLog_ERR(TAG, "not enough data!");
-        return ERROR_INVALID_DATA;
-    }
+       if (Stream_GetRemainingLength(s) < sizeof(UINT16))
+       {
+               WLog_ERR(TAG, "not enough data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */
+
        if (pdu.capsSetCount > 3)
        {
                /* According to the latest spec, capsSetCount <= 3 */
@@ -1157,12 +1175,12 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream
                return ERROR_INVALID_DATA;
        }
 
-    if (Stream_GetRemainingLength(s) < 
-          (pdu.capsSetCount * (sizeof(RDPGFX_CAPSET) + sizeof(UINT32))))
-    {
-        WLog_ERR(TAG, "not enough data!");
-        return ERROR_INVALID_DATA;
-    }
+       if (Stream_GetRemainingLength(s) <
+                       (pdu.capsSetCount * (sizeof(RDPGFX_CAPSET) + sizeof(UINT32))))
+       {
+               WLog_ERR(TAG, "not enough data!");
+               return ERROR_INVALID_DATA;
+       }
 
        pdu.capsSets = (RDPGFX_CAPSET*) capsSets;
 
@@ -1171,17 +1189,21 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream
                capsSet = &(pdu.capsSets[index]);
                Stream_Read_UINT32(s, capsSet->version); /* version (4 bytes) */
                Stream_Read_UINT32(s, capsDataLength); /* capsDataLength (4 bytes) */
+
                if (capsDataLength != 4)
                {
-                       WLog_ERR(TAG, "capsDataLength does not equal to 4: %lu", capsDataLength);
+                       WLog_ERR(TAG, "capsDataLength does not equal to 4: %lu",
+                                        capsDataLength);
                        return ERROR_INVALID_DATA;
                }
+
                Stream_Read_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
        }
 
        if (context)
        {
                IFCALLRET(context->CapsAdvertise, error, context, &pdu);
+
                if (error)
                        WLog_ERR(TAG, "context->CapsAdvertise failed with error %lu", error);
        }
@@ -1194,16 +1216,17 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context, wStream* s)
+static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context,
+               wStream* s)
 {
        RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU pdu;
        UINT error = CHANNEL_RC_OK;
 
-    if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU))
-    {
-        WLog_ERR(TAG, "not enough data!");
-        return ERROR_INVALID_DATA;
-    }
+       if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU))
+       {
+               WLog_ERR(TAG, "not enough data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */
        Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */
@@ -1213,8 +1236,10 @@ static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context,
        if (context)
        {
                IFCALLRET(context->QoeFrameAcknowledge, error, context, &pdu);
+
                if (error)
-                       WLog_ERR(TAG, "context->QoeFrameAcknowledge failed with error %lu", error);
+                       WLog_ERR(TAG, "context->QoeFrameAcknowledge failed with error %lu",
+                                        error);
        }
 
        return error;
@@ -1230,7 +1255,6 @@ static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s)
        int beg, end;
        RDPGFX_HEADER header;
        UINT error = CHANNEL_RC_OK;
-
        beg = Stream_GetPosition(s);
 
        if ((error = rdpgfx_read_header(s, &header)))
@@ -1240,30 +1264,39 @@ static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s)
        }
 
        WLog_DBG(TAG, "cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d",
-                       rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength);
+                        rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId,
+                        header.flags, header.pduLength);
 
        switch (header.cmdId)
        {
                case RDPGFX_CMDID_FRAMEACKNOWLEDGE:
+
                        if ((error = rdpgfx_recv_frame_acknowledge_pdu(context, s)))
-                               WLog_ERR(TAG, "rdpgfx_recv_frame_acknowledge_pdu failed with error %lu!", error);
-                       break;
+                               WLog_ERR(TAG, "rdpgfx_recv_frame_acknowledge_pdu "
+                                                "failed with error %lu!", error);
 
+                       break;
                case RDPGFX_CMDID_CACHEIMPORTOFFER:
+
                        if ((error = rdpgfx_recv_cache_import_offer_pdu(context, s)))
-                               WLog_ERR(TAG, "rdpgfx_recv_cache_import_offer_pdu failed with error %lu!", error);
-                       break;
+                               WLog_ERR(TAG, "rdpgfx_recv_cache_import_offer_pdu "
+                                                "failed with error %lu!", error);
 
+                       break;
                case RDPGFX_CMDID_CAPSADVERTISE:
+
                        if ((error = rdpgfx_recv_caps_advertise_pdu(context, s)))
-                               WLog_ERR(TAG, "rdpgfx_recv_caps_advertise_pdu failed with error %lu!", error);
-                       break;
+                               WLog_ERR(TAG, "rdpgfx_recv_caps_advertise_pdu "
+                                                "failed with error %lu!", error);
 
+                       break;
                case RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE:
+
                        if ((error = rdpgfx_recv_qoe_frame_acknowledge_pdu(context, s)))
-                               WLog_ERR(TAG, "rdpgfx_recv_qoe_frame_acknowledge_pdu failed with error %lu!", error);
-                       break;
+                               WLog_ERR(TAG, "rdpgfx_recv_qoe_frame_acknowledge_pdu "
+                                                "failed with error %lu!", error);
 
+                       break;
                default:
                        error = CHANNEL_RC_BAD_PROC;
                        break;
@@ -1281,90 +1314,31 @@ static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s)
        if (end != (beg + header.pduLength))
        {
                WLog_ERR(TAG,  "Unexpected gfx pdu end: Actual: %d, Expected: %d",
-                        end, (beg + header.pduLength));
+                                end, (beg + header.pduLength));
                Stream_SetPosition(s, (beg + header.pduLength));
        }
 
        return error;
-       
 }
 
 static void* rdpgfx_server_thread_func(void* arg)
 {
        RdpgfxServerContext* context = (RdpgfxServerContext*) arg;
        RdpgfxServerPrivate* priv = context->priv;
-       wStream* s;
        DWORD status;
        DWORD nCount;
        void* buffer;
        HANDLE events[8];
-       HANDLE ChannelEvent;
        DWORD BytesReturned = 0;
        UINT error = CHANNEL_RC_OK;
-       BOOL ready = FALSE;
-
        buffer = NULL;
        BytesReturned = 0;
-       ChannelEvent = NULL;
-
-       /* Query for channel event handle */
-       if (WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
-       {
-               if (BytesReturned == sizeof(HANDLE))
-                       CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
-
-               WTSFreeMemory(buffer);
-       }
-       else
-       {
-               WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
-               error = ERROR_INTERNAL_ERROR;
-               goto out;
-       }
-
        nCount = 0;
        events[nCount++] = priv->stopEvent;
-       events[nCount++] = ChannelEvent;
-
-       /* Wait for the client to confirm that the dynamic channel is ready */
-       while (1)
-       {
-               if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0)
-                       goto out;
-
-               if (status == WAIT_FAILED)
-               {
-                       error = GetLastError();
-                       WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
-                       goto out;
-               }
-
-               if (WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE)
-               {
-                       WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
-                       error = ERROR_INTERNAL_ERROR;
-                       goto out;
-               }
-
-               ready = *((BOOL*) buffer);
-
-               WTSFreeMemory(buffer);
-
-               if (ready)
-                       break;
-       }
-
-       /* Create shared stream */
-       s = Stream_New(NULL, 4096);
-       if (!s)
-       {
-               WLog_ERR(TAG, "Stream_New failed!");
-               error = CHANNEL_RC_NO_MEMORY;
-               goto out;
-       }
+       events[nCount++] = priv->channelEvent;
 
        /* Main virtual channel loop. RDPGFX do not need version negotiation */
-       while (ready)
+       while (TRUE)
        {
                status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
 
@@ -1372,65 +1346,24 @@ static void* rdpgfx_server_thread_func(void* arg)
                {
                        error = GetLastError();
                        WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
-                       goto out;
-               }
-
-               /* Stop Event */ 
-               if (status == WAIT_OBJECT_0)
-                       break;
-
-               /* Channel Event */
-               Stream_SetPosition(s, 0);
-
-               if (!WTSVirtualChannelRead(priv->rdpgfx_channel, 0, NULL, 0, &BytesReturned))
-               {
-                       WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
-                       error = ERROR_INTERNAL_ERROR;
-                       break;
-               }
-
-               if (BytesReturned < 1)
-                       continue;
-
-               if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
-               {
-                       WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
-                       error = CHANNEL_RC_NO_MEMORY;
                        break;
                }
 
-               if (WTSVirtualChannelRead(priv->rdpgfx_channel, 0, (PCHAR) Stream_Buffer(s),
-                       Stream_Capacity(s), &BytesReturned) == FALSE)
-               {
-                       WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
-                       error = ERROR_INTERNAL_ERROR;
+               /* Stop Event */
+               if (status == WAIT_OBJECT_0)
                        break;
-               }
 
-               Stream_SetLength(s, BytesReturned);
-               Stream_SetPosition(s, 0);
-
-               while (((size_t) Stream_GetPosition(s)) < Stream_Length(s))
-               {
-                       if ((error = rdpgfx_server_receive_pdu(context, s)))
-                       {
-                               WLog_ERR(TAG, "rdpgfx_server_receive_pdu failed with error %lu!", error);
-                               break;
-                       }
-               }
-
-               if (error != CHANNEL_RC_OK)
+               if ((error = rdpgfx_server_handle_messages(context)))
                {
+                       WLog_ERR(TAG, "rdpgfx_server_handle_messages failed with error %lu",
+                                        error);
                        break;
                }
        }
 
-       Stream_Free(s, TRUE);
-out:
-       WTSVirtualChannelClose(priv->rdpgfx_channel);
-       priv->rdpgfx_channel = NULL;
        if (error && context->rdpcontext)
-               setChannelError(context->rdpcontext, error, "rdpgfx_server_thread_func reported an error");
+               setChannelError(context->rdpcontext, error,
+                                               "rdpgfx_server_thread_func reported an error");
 
        ExitThread((DWORD)error);
        return NULL;
@@ -1438,24 +1371,28 @@ out:
 
 static BOOL rdpgfx_server_open(RdpgfxServerContext* context)
 {
-       RdpgfxServerPrivate* priv = (RdpgfxServerPrivate *) context->priv;
+       RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv;
+       void* buffer = NULL;
 
-       if (!priv->thread)
+       if (!priv->isOpened)
        {
                PULONG pSessionId = NULL;
                DWORD BytesReturned = 0;
-
                priv->SessionId = WTS_CURRENT_SESSION;
 
                if (WTSQuerySessionInformationA(context->vcm, WTS_CURRENT_SESSION,
-                               WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned))
+                                                                               WTSSessionId, (LPSTR*) &pSessionId,
+                                                                               &BytesReturned) == FALSE)
                {
-                       priv->SessionId = (DWORD) *pSessionId;
-                       WTSFreeMemory(pSessionId);
+                       WLog_ERR(TAG, "WTSQuerySessionInformationA failed!");
+                       return FALSE;
                }
 
+               priv->SessionId = (DWORD) *pSessionId;
+               WTSFreeMemory(pSessionId);
                priv->rdpgfx_channel = WTSVirtualChannelOpenEx(priv->SessionId,
-                               RDPGFX_DVC_CHANNEL_NAME, WTS_CHANNEL_OPTION_DYNAMIC);
+                                                          RDPGFX_DVC_CHANNEL_NAME,
+                                                          WTS_CHANNEL_OPTION_DYNAMIC);
 
                if (!priv->rdpgfx_channel)
                {
@@ -1463,56 +1400,80 @@ static BOOL rdpgfx_server_open(RdpgfxServerContext* context)
                        return FALSE;
                }
 
-               if (!(priv->zgfx = zgfx_context_new(TRUE)))
+               /* Query for channel event handle */
+               if (!WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualEventHandle,
+                                                                       &buffer, &BytesReturned)
+                               || (BytesReturned != sizeof(HANDLE)))
                {
-                       WLog_ERR(TAG, "Create zgfx context failed!");
+                       WLog_ERR(TAG,  "WTSVirtualChannelQuery failed "
+                                        "or invalid returned size(%d)",
+                                        BytesReturned);
+
+                       if (buffer)
+                               WTSFreeMemory(buffer);
+
                        goto out_close;
                }
 
-               if (!(priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
+               CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE));
+               WTSFreeMemory(buffer);
+
+               if (!(priv->zgfx = zgfx_context_new(TRUE)))
                {
-                       WLog_ERR(TAG, "CreateEvent failed!");
-                       goto out_zgfx;
+                       WLog_ERR(TAG, "Create zgfx context failed!");
+                       goto out_close;
                }
 
-               if (!(priv->thread = CreateThread(NULL, 0,
-                               (LPTHREAD_START_ROUTINE) rdpgfx_server_thread_func, (void*) context, 0, NULL)))
+               if (priv->ownThread)
                {
-                       WLog_ERR(TAG, "CreateThread failed!");
-                       goto out_stopEvent;
+                       if (!(priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
+                       {
+                               WLog_ERR(TAG, "CreateEvent failed!");
+                               goto out_zgfx;
+                       }
+
+                       if (!(priv->thread = CreateThread(NULL, 0,
+                                                                                         (LPTHREAD_START_ROUTINE)
+                                                                                         rdpgfx_server_thread_func,
+                                                                                         (void*) context, 0, NULL)))
+                       {
+                               WLog_ERR(TAG, "CreateThread failed!");
+                               goto out_stopEvent;
+                       }
                }
 
+               priv->isOpened = TRUE;
+               priv->isReady = FALSE;
                return TRUE;
        }
 
-       WLog_ERR(TAG, "thread already running!");
+       WLog_ERR(TAG, "RDPGFX channel is already opened!");
        return FALSE;
-
 out_stopEvent:
        CloseHandle(priv->stopEvent);
        priv->stopEvent = NULL;
-
 out_zgfx:
        zgfx_context_free(priv->zgfx);
        priv->zgfx = NULL;
-
 out_close:
        WTSVirtualChannelClose(priv->rdpgfx_channel);
        priv->rdpgfx_channel = NULL;
-
+       priv->channelEvent = NULL;
        return FALSE;
 }
 
 static BOOL rdpgfx_server_close(RdpgfxServerContext* context)
 {
-       RdpgfxServerPrivate* priv = (RdpgfxServerPrivate *) context->priv;
+       RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv;
 
-       if (priv->thread)
+       if (priv->ownThread && priv->thread)
        {
                SetEvent(priv->stopEvent);
+
                if (WaitForSingleObject(priv->thread, INFINITE) == WAIT_FAILED)
                {
-                       WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError());
+                       WLog_ERR(TAG, "WaitForSingleObject failed with error %lu",
+                                        GetLastError());
                        return FALSE;
                }
 
@@ -1531,15 +1492,18 @@ static BOOL rdpgfx_server_close(RdpgfxServerContext* context)
                priv->rdpgfx_channel = NULL;
        }
 
+       priv->channelEvent = NULL;
+       priv->isOpened = FALSE;
+       priv->isReady = FALSE;
        return TRUE;
 }
 
 RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm)
 {
        RdpgfxServerContext* context;
-       RdpgfxServerPrivate *priv;
+       RdpgfxServerPrivate* priv;
+       context = (RdpgfxServerContext*)calloc(1, sizeof(RdpgfxServerContext));
 
-       context = (RdpgfxServerContext *)calloc(1, sizeof(RdpgfxServerContext));
        if (!context)
        {
                WLog_ERR(TAG, "calloc failed!");
@@ -1549,7 +1513,6 @@ RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm)
        context->vcm = vcm;
        context->Open = rdpgfx_server_open;
        context->Close = rdpgfx_server_close;
-
        context->ResetGraphics = rdpgfx_send_reset_graphics_pdu;
        context->StartFrame = rdpgfx_send_start_frame_pdu;
        context->EndFrame = rdpgfx_send_end_frame_pdu;
@@ -1571,16 +1534,30 @@ RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm)
        context->CapsConfirm = rdpgfx_send_caps_confirm_pdu;
        context->FrameAcknowledge = NULL;
        context->QoeFrameAcknowledge = NULL;
+       context->priv = priv = (RdpgfxServerPrivate*)
+                                                  calloc(1, sizeof(RdpgfxServerPrivate));
 
-       context->priv = priv = (RdpgfxServerPrivate *)calloc(1, sizeof(RdpgfxServerPrivate));
        if (!priv)
        {
                WLog_ERR(TAG, "calloc failed!");
                goto out_free;
        }
 
-       return (RdpgfxServerContext*) context;
+       /* Create shared input stream */
+       priv->input_stream = Stream_New(NULL, 4);
 
+       if (!priv->input_stream)
+       {
+               WLog_ERR(TAG, "Stream_New failed!");
+               goto out_free_priv;
+       }
+
+       priv->isOpened = FALSE;
+       priv->isReady = FALSE;
+       priv->ownThread = TRUE;
+       return (RdpgfxServerContext*) context;
+out_free_priv:
+       free(context->priv);
 out_free:
        free(context);
        return NULL;
@@ -1590,7 +1567,98 @@ void rdpgfx_server_context_free(RdpgfxServerContext* context)
 {
        rdpgfx_server_close(context);
 
-       free(context->priv);
+       if (context->priv)
+               Stream_Free(context->priv->input_stream, TRUE);
 
+       free(context->priv);
        free(context);
 }
+
+FREERDP_API HANDLE rdpgfx_server_get_event_handle(RdpgfxServerContext* context)
+{
+       return context->priv->channelEvent;
+}
+
+/*
+ * Handle rpdgfx messages - server side
+ *
+ * @param Server side context
+ *
+ * @return 0 on success
+ *         ERROR_NO_DATA if no data could be read this time
+ *         otherwise a Win32 error code
+ */
+UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context)
+{
+       DWORD BytesReturned;
+       void* buffer;
+       UINT ret = CHANNEL_RC_OK;
+       RdpgfxServerPrivate* priv = context->priv;
+       wStream* s = priv->input_stream;
+
+       /* Check whether the dynamic channel is ready */
+       if (!priv->isReady)
+       {
+               if (WTSVirtualChannelQuery(priv->rdpgfx_channel,
+                                                                  WTSVirtualChannelReady,
+                                                                  &buffer, &BytesReturned) == FALSE)
+               {
+                       if (GetLastError() == ERROR_NO_DATA)
+                               return ERROR_NO_DATA;
+
+                       WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
+                       return ERROR_INTERNAL_ERROR;
+               }
+
+               priv->isReady = *((BOOL*) buffer);
+               WTSFreeMemory(buffer);
+       }
+
+       /* Consume channel event only after the gfx dynamic channel is ready */
+       if (priv->isReady)
+       {
+               Stream_SetPosition(s, 0);
+
+               if (!WTSVirtualChannelRead(priv->rdpgfx_channel,
+                                                                  0, NULL, 0, &BytesReturned))
+               {
+                       if (GetLastError() == ERROR_NO_DATA)
+                               return ERROR_NO_DATA;
+
+                       WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
+                       return ERROR_INTERNAL_ERROR;
+               }
+
+               if (BytesReturned < 1)
+                       return CHANNEL_RC_OK;
+
+               if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
+               {
+                       WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
+                       return CHANNEL_RC_NO_MEMORY;
+               }
+
+               if (WTSVirtualChannelRead(priv->rdpgfx_channel, 0,
+                                                                 (PCHAR) Stream_Buffer(s),
+                                                                 Stream_Capacity(s), &BytesReturned) == FALSE)
+               {
+                       WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
+                       return ERROR_INTERNAL_ERROR;
+               }
+
+               Stream_SetLength(s, BytesReturned);
+               Stream_SetPosition(s, 0);
+
+               while (((size_t) Stream_GetPosition(s)) < Stream_Length(s))
+               {
+                       if ((ret = rdpgfx_server_receive_pdu(context, s)))
+                       {
+                               WLog_ERR(TAG, "rdpgfx_server_receive_pdu "
+                                                "failed with error %lu!", ret);
+                               return ret;
+                       }
+               }
+       }
+
+       return ret;
+}
index caad8cc..be29b76 100644 (file)
 struct _rdpgfx_server_private
 {
        ZGFX_CONTEXT* zgfx;
+       BOOL ownThread;
        HANDLE thread;
        HANDLE stopEvent;
+       HANDLE channelEvent;
        void* rdpgfx_channel;
        DWORD SessionId;
-       BOOL opened;
+       wStream* input_stream;
+       BOOL isOpened;
+       BOOL isReady;
 };
 
 #endif /* FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H */
index 983779e..fad7789 100644 (file)
@@ -28,27 +28,27 @@ typedef struct _rdpgfx_server_private RdpgfxServerPrivate;
 typedef BOOL (*psRdpgfxServerOpen)(RdpgfxServerContext* context);
 typedef BOOL (*psRdpgfxServerClose)(RdpgfxServerContext* context);
 
-typedef UINT (*psRdpgfxResetGraphics)(RdpgfxServerContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics);
-typedef UINT (*psRdpgfxStartFrame)(RdpgfxServerContext* context, RDPGFX_START_FRAME_PDU* startFrame);
-typedef UINT (*psRdpgfxEndFrame)(RdpgfxServerContext* context, RDPGFX_END_FRAME_PDU* endFrame);
-typedef UINT (*psRdpgfxSurfaceCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd);
-typedef UINT (*psRdpgfxSurfaceFrameCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, RDPGFX_END_FRAME_PDU* endFrame);
-typedef UINT (*psRdpgfxDeleteEncodingContext)(RdpgfxServerContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext);
-typedef UINT (*psRdpgfxCreateSurface)(RdpgfxServerContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface);
-typedef UINT (*psRdpgfxDeleteSurface)(RdpgfxServerContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface);
-typedef UINT (*psRdpgfxSolidFill)(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_PDU* solidFill);
-typedef UINT (*psRdpgfxSurfaceToSurface)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface);
-typedef UINT (*psRdpgfxSurfaceToCache)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache);
-typedef UINT (*psRdpgfxCacheToSurface)(RdpgfxServerContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface);
-typedef UINT (*psRdpgfxCacheImportOffer)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_OFFER_PDU* cacheImportOffer);
-typedef UINT (*psRdpgfxCacheImportReply)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply);
-typedef UINT (*psRdpgfxEvictCacheEntry)(RdpgfxServerContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry);
-typedef UINT (*psRdpgfxMapSurfaceToOutput)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput);
-typedef UINT (*psRdpgfxMapSurfaceToWindow)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow);
-typedef UINT (*psRdpgfxCapsAdvertise)(RdpgfxServerContext* context, RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise);
-typedef UINT (*psRdpgfxCapsConfirm)(RdpgfxServerContext* context, RDPGFX_CAPS_CONFIRM_PDU* capsConfirm);
-typedef UINT (*psRdpgfxFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge);
-typedef UINT (*psRdpgfxQoeFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge);
+typedef UINT(*psRdpgfxResetGraphics)(RdpgfxServerContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics);
+typedef UINT(*psRdpgfxStartFrame)(RdpgfxServerContext* context, RDPGFX_START_FRAME_PDU* startFrame);
+typedef UINT(*psRdpgfxEndFrame)(RdpgfxServerContext* context, RDPGFX_END_FRAME_PDU* endFrame);
+typedef UINT(*psRdpgfxSurfaceCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd);
+typedef UINT(*psRdpgfxSurfaceFrameCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, RDPGFX_END_FRAME_PDU* endFrame);
+typedef UINT(*psRdpgfxDeleteEncodingContext)(RdpgfxServerContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext);
+typedef UINT(*psRdpgfxCreateSurface)(RdpgfxServerContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface);
+typedef UINT(*psRdpgfxDeleteSurface)(RdpgfxServerContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface);
+typedef UINT(*psRdpgfxSolidFill)(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_PDU* solidFill);
+typedef UINT(*psRdpgfxSurfaceToSurface)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface);
+typedef UINT(*psRdpgfxSurfaceToCache)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache);
+typedef UINT(*psRdpgfxCacheToSurface)(RdpgfxServerContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface);
+typedef UINT(*psRdpgfxCacheImportOffer)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_OFFER_PDU* cacheImportOffer);
+typedef UINT(*psRdpgfxCacheImportReply)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply);
+typedef UINT(*psRdpgfxEvictCacheEntry)(RdpgfxServerContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry);
+typedef UINT(*psRdpgfxMapSurfaceToOutput)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput);
+typedef UINT(*psRdpgfxMapSurfaceToWindow)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow);
+typedef UINT(*psRdpgfxCapsAdvertise)(RdpgfxServerContext* context, RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise);
+typedef UINT(*psRdpgfxCapsConfirm)(RdpgfxServerContext* context, RDPGFX_CAPS_CONFIRM_PDU* capsConfirm);
+typedef UINT(*psRdpgfxFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge);
+typedef UINT(*psRdpgfxQoeFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge);
 
 struct _rdpgfx_server_context
 {
@@ -90,6 +90,8 @@ extern "C" {
 
 FREERDP_API RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm);
 FREERDP_API void rdpgfx_server_context_free(RdpgfxServerContext* context);
+FREERDP_API HANDLE rdpgfx_server_get_event_handle(RdpgfxServerContext* context);
+FREERDP_API UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context);
 
 #ifdef __cplusplus
 }