diff --git a/cunit/test_orders.c b/cunit/test_orders.c index 2eb1187b2..35d062752 100644 --- a/cunit/test_orders.c +++ b/cunit/test_orders.c @@ -47,14 +47,21 @@ int add_orders_suite(void) add_test_function(read_scrblt_order); add_test_function(read_opaque_rect_order); add_test_function(read_draw_nine_grid_order); + add_test_function(read_multi_opaque_rect_order); add_test_function(read_line_to_order); + add_test_function(read_polyline_order); add_test_function(read_glyph_index_order); add_test_function(read_fast_index_order); add_test_function(read_fast_glyph_order); + add_test_function(read_polygon_cb_order); add_test_function(read_cache_bitmap_order); add_test_function(read_cache_bitmap_v2_order); add_test_function(read_cache_bitmap_v3_order); + add_test_function(read_cache_brush_order); + + add_test_function(read_create_offscreen_bitmap_order); + add_test_function(read_switch_surface_order); return 0; } @@ -199,6 +206,57 @@ void test_read_draw_nine_grid_order(void) CU_ASSERT(stream_get_length(s) == (sizeof(draw_nine_grid_order) - 1)); } + +uint8 multi_opaque_rect_order[] = + "\x87\x01\x1c\x01\xf1\x00\x12\x00\x5c\xef\x04\x16\x00\x08\x40\x81" + "\x87\x81\x1c\x80\xf1\x01\x01\x01\x10\x80\xf0\x01\x10\xff\x10\x10" + "\x80\xf1\x01"; + +void test_read_multi_opaque_rect_order(void) +{ + STREAM* s; + MULTI_OPAQUE_RECT_ORDER multi_opaque_rect; + + s = stream_new(0); + s->p = s->data = multi_opaque_rect_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x01BF; + memset(&multi_opaque_rect, 0, sizeof(MULTI_OPAQUE_RECT_ORDER)); + + update_read_multi_opaque_rect_order(s, orderInfo, &multi_opaque_rect); + + CU_ASSERT(multi_opaque_rect.nLeftRect == 391); + CU_ASSERT(multi_opaque_rect.nTopRect == 284); + CU_ASSERT(multi_opaque_rect.nWidth == 241); + CU_ASSERT(multi_opaque_rect.nHeight == 18); + CU_ASSERT(multi_opaque_rect.color == 0x0000EF5C); + CU_ASSERT(multi_opaque_rect.cbData == 22); + CU_ASSERT(multi_opaque_rect.numRectangles == 4); + + CU_ASSERT(multi_opaque_rect.rectangles[1].left == 391); + CU_ASSERT(multi_opaque_rect.rectangles[1].top == 284); + CU_ASSERT(multi_opaque_rect.rectangles[1].width == 241); + CU_ASSERT(multi_opaque_rect.rectangles[1].height == 1); + + CU_ASSERT(multi_opaque_rect.rectangles[2].left == 391); + CU_ASSERT(multi_opaque_rect.rectangles[2].top == 285); + CU_ASSERT(multi_opaque_rect.rectangles[2].width == 1); + CU_ASSERT(multi_opaque_rect.rectangles[2].height == 16); + + CU_ASSERT(multi_opaque_rect.rectangles[3].left == 631); + CU_ASSERT(multi_opaque_rect.rectangles[3].top == 285); + CU_ASSERT(multi_opaque_rect.rectangles[3].width == 1); + CU_ASSERT(multi_opaque_rect.rectangles[3].height == 16); + + CU_ASSERT(multi_opaque_rect.rectangles[4].left == 391); + CU_ASSERT(multi_opaque_rect.rectangles[4].top == 301); + CU_ASSERT(multi_opaque_rect.rectangles[4].width == 241); + CU_ASSERT(multi_opaque_rect.rectangles[4].height == 1); + + CU_ASSERT(stream_get_length(s) == (sizeof(multi_opaque_rect_order) - 1)); +} + uint8 line_to_order[] = "\x03\xb1\x0e\xa6\x5b\xef\x00"; void test_read_line_to_order(void) @@ -238,6 +296,106 @@ void test_read_line_to_order(void) CU_ASSERT(stream_get_length(s) == (sizeof(line_to_order) - 1)); } +uint8 polyline_order[] = + "\xf8\x01\xb8\x02\x00\xc0\x00\x20\x6c\x00\x00\x00\x00\x00\x04\x00" + "\x00\xff\x7e\x76\xff\x41\x6c\xff\x24\x62\xff\x2b\x59\xff\x55\x51" + "\xff\x9c\x49\x73\x43\x80\x4d\xff\xbe\x80\x99\xff\xba\x80\xcd\xff" + "\xb7\x80\xde\xff\xb6\x80\xca\xff\xb6\x80\x96\xff\xb7\x80\x48\xff" + "\xba\x6f\xff\xbe\xff\x97\x43\xff\x52\x4a\xff\x2b\x51\xff\x24\x59" + "\xff\x44\x63\xff\x81\x6c\x56\x76\x2f\x80\x82\x0a\x80\xbf\x14\x80" + "\xdd\x1e\x80\xd4\x27\x80\xab\x2f\x80\x64\x37\x0d\x3d\xff\xb3\x80" + "\x42\xff\x67\x80\x46"; + +void test_read_polyline_order(void) +{ + STREAM* s; + POLYLINE_ORDER polyline; + + s = stream_new(0); + s->p = s->data = polyline_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x73; + + memset(&polyline, 0, sizeof(POLYLINE_ORDER)); + + update_read_polyline_order(s, orderInfo, &polyline); + + CU_ASSERT(polyline.xStart == 504); + CU_ASSERT(polyline.yStart == 696); + CU_ASSERT(polyline.bRop2 == 0); + CU_ASSERT(polyline.penColor == 0x0000C000); + CU_ASSERT(polyline.numPoints == 32); + CU_ASSERT(polyline.cbData == 108); + + CU_ASSERT(polyline.points[1].x == 374); + CU_ASSERT(polyline.points[1].y == 686); + CU_ASSERT(polyline.points[2].x == 183); + CU_ASSERT(polyline.points[2].y == 666); + CU_ASSERT(polyline.points[3].x == -37); + CU_ASSERT(polyline.points[3].y == 636); + CU_ASSERT(polyline.points[4].x == -250); + CU_ASSERT(polyline.points[4].y == 597); + CU_ASSERT(polyline.points[5].x == -421); + CU_ASSERT(polyline.points[5].y == 550); + CU_ASSERT(polyline.points[6].x == -521); + CU_ASSERT(polyline.points[6].y == 495); + CU_ASSERT(polyline.points[7].x == -534); + CU_ASSERT(polyline.points[7].y == 434); + CU_ASSERT(polyline.points[8].x == -457); + CU_ASSERT(polyline.points[8].y == 368); + CU_ASSERT(polyline.points[9].x == -304); + CU_ASSERT(polyline.points[9].y == 298); + CU_ASSERT(polyline.points[10].x == -99); + CU_ASSERT(polyline.points[10].y == 225); + CU_ASSERT(polyline.points[11].x == 123); + CU_ASSERT(polyline.points[11].y == 151); + CU_ASSERT(polyline.points[12].x == 325); + CU_ASSERT(polyline.points[12].y == 77); + CU_ASSERT(polyline.points[13].x == 475); + CU_ASSERT(polyline.points[13].y == 4); + CU_ASSERT(polyline.points[14].x == 547); + CU_ASSERT(polyline.points[14].y == -66); + CU_ASSERT(polyline.points[15].x == 530); + CU_ASSERT(polyline.points[15].y == -132); + CU_ASSERT(polyline.points[16].x == 425); + CU_ASSERT(polyline.points[16].y == -193); + CU_ASSERT(polyline.points[17].x == 251); + CU_ASSERT(polyline.points[17].y == -247); + CU_ASSERT(polyline.points[18].x == 38); + CU_ASSERT(polyline.points[18].y == -294); + CU_ASSERT(polyline.points[19].x == -182); + CU_ASSERT(polyline.points[19].y == -333); + CU_ASSERT(polyline.points[20].x == -370); + CU_ASSERT(polyline.points[20].y == -362); + CU_ASSERT(polyline.points[21].x == -497); + CU_ASSERT(polyline.points[21].y == -382); + CU_ASSERT(polyline.points[22].x == -539); + CU_ASSERT(polyline.points[22].y == -392); + CU_ASSERT(polyline.points[23].x == -492); + CU_ASSERT(polyline.points[23].y == -392); + CU_ASSERT(polyline.points[24].x == -362); + CU_ASSERT(polyline.points[24].y == -382); + CU_ASSERT(polyline.points[25].x == -171); + CU_ASSERT(polyline.points[25].y == -362); + CU_ASSERT(polyline.points[26].x == 50); + CU_ASSERT(polyline.points[26].y == -332); + CU_ASSERT(polyline.points[27].x == 262); + CU_ASSERT(polyline.points[27].y == -293); + CU_ASSERT(polyline.points[28].x == 433); + CU_ASSERT(polyline.points[28].y == -246); + CU_ASSERT(polyline.points[29].x == 533); + CU_ASSERT(polyline.points[29].y == -191); + CU_ASSERT(polyline.points[30].x == 546); + CU_ASSERT(polyline.points[30].y == -130); + CU_ASSERT(polyline.points[31].x == 469); + CU_ASSERT(polyline.points[31].y == -64); + CU_ASSERT(polyline.points[32].x == 316); + CU_ASSERT(polyline.points[32].y == 6); + + CU_ASSERT(stream_get_length(s) == (sizeof(polyline_order) - 1)); +} + uint8 glyph_index_order_1[] = "\x6a\x02\x27\x38\x00\x39\x07\x3a\x06\x3b\x07\x3c\x06\x3d\x06\x18" "\x04\x1f\x06\x17\x02\x14\x04\x1b\x06\x19\x06\x45\x05\x18\x06\x1f" @@ -370,6 +528,40 @@ void test_read_fast_glyph_order(void) CU_ASSERT(stream_get_length(s) == (sizeof(fast_glyph_order) - 1)); } +uint8 polygon_cb_order[] = + "\xea\x00\x46\x01\x0d\x01\x08\x00\x00\x04\x03\x81\x08\x03\x05\x88" + "\x09\x26\x09\x77"; + +void test_read_polygon_cb_order(void) +{ + STREAM* s; + POLYGON_CB_ORDER polygon_cb; + + s = stream_new(0); + s->p = s->data = polygon_cb_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x1BEF; + + memset(&polygon_cb, 0, sizeof(POLYGON_CB_ORDER)); + + update_read_polygon_cb_order(s, orderInfo, &polygon_cb); + + CU_ASSERT(polygon_cb.xStart == 234); + CU_ASSERT(polygon_cb.yStart == 326); + CU_ASSERT(polygon_cb.bRop2 == 0x0D); + CU_ASSERT(polygon_cb.fillMode == 1); + CU_ASSERT(polygon_cb.backColor == 0); + CU_ASSERT(polygon_cb.foreColor == 0x00000008); + CU_ASSERT(polygon_cb.brushOrgX == 4); + CU_ASSERT(polygon_cb.brushOrgY == 3); + CU_ASSERT(polygon_cb.brushStyle == 0x81); + CU_ASSERT(polygon_cb.nDeltaEntries == 3); + CU_ASSERT(polygon_cb.cbData == 5); + + CU_ASSERT(stream_get_length(s) == (sizeof(polygon_cb_order) - 1)); +} + uint8 cache_bitmap_order[] = "\x00\x00\x10\x01\x08\x01\x00\x00\x00\x10"; void test_read_cache_bitmap_order(void) @@ -472,3 +664,68 @@ void test_read_cache_bitmap_v3_order(void) CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_v3_order) - 1)); } +uint8 cache_brush_order[] = "\x00\x01\x08\x08\x81\x08\xaa\x55\xaa\x55\xaa\x55\xaa\x55"; + +void test_read_cache_brush_order(void) +{ + STREAM* s; + CACHE_BRUSH_ORDER cache_brush; + + s = stream_new(0); + s->p = s->data = cache_brush_order; + + memset(&cache_brush, 0, sizeof(CACHE_BRUSH_ORDER)); + + update_read_cache_brush_order(s, &cache_brush, 0); + + CU_ASSERT(cache_brush.cacheEntry == 0); + CU_ASSERT(cache_brush.bpp == 1); + CU_ASSERT(cache_brush.cx == 8); + CU_ASSERT(cache_brush.cy == 8); + CU_ASSERT(cache_brush.style == 0x81); + CU_ASSERT(cache_brush.length == 8); + + CU_ASSERT(stream_get_length(s) == (sizeof(cache_brush_order) - 1)); +} + +uint8 create_offscreen_bitmap_order[] = "\x00\x80\x60\x01\x10\x00\x01\x00\x02\x00"; + +void test_read_create_offscreen_bitmap_order(void) +{ + STREAM* s; + CREATE_OFFSCREEN_BITMAP_ORDER create_offscreen_bitmap; + + s = stream_new(0); + s->p = s->data = create_offscreen_bitmap_order; + + memset(&create_offscreen_bitmap, 0, sizeof(CREATE_OFFSCREEN_BITMAP_ORDER)); + + update_read_create_offscreen_bitmap_order(s, &create_offscreen_bitmap); + + CU_ASSERT(create_offscreen_bitmap.id == 0); + CU_ASSERT(create_offscreen_bitmap.cx == 352); + CU_ASSERT(create_offscreen_bitmap.cy == 16); + CU_ASSERT(create_offscreen_bitmap.deleteList.cIndices == 1); + + CU_ASSERT(stream_get_length(s) == (sizeof(create_offscreen_bitmap_order) - 1)); +} + +uint8 switch_surface_order[] = "\xff\xff"; + +void test_read_switch_surface_order(void) +{ + STREAM* s; + SWITCH_SURFACE_ORDER switch_surface; + + s = stream_new(0); + s->p = s->data = switch_surface_order; + + memset(&switch_surface, 0, sizeof(SWITCH_SURFACE_ORDER)); + + update_read_switch_surface_order(s, &switch_surface); + + CU_ASSERT(switch_surface.bitmapId == 0xFFFF); + + CU_ASSERT(stream_get_length(s) == (sizeof(switch_surface_order) - 1)); +} + diff --git a/cunit/test_orders.h b/cunit/test_orders.h index b90fcbbbc..cdac6825c 100644 --- a/cunit/test_orders.h +++ b/cunit/test_orders.h @@ -28,11 +28,18 @@ void test_read_patblt_order(void); void test_read_scrblt_order(void); void test_read_opaque_rect_order(void); void test_read_draw_nine_grid_order(void); +void test_read_multi_opaque_rect_order(void); void test_read_line_to_order(void); +void test_read_polyline_order(void); void test_read_glyph_index_order(void); void test_read_fast_index_order(void); void test_read_fast_glyph_order(void); +void test_read_polygon_cb_order(void); void test_read_cache_bitmap_order(void); void test_read_cache_bitmap_v2_order(void); void test_read_cache_bitmap_v3_order(void); +void test_read_cache_brush_order(void); + +void test_read_create_offscreen_bitmap_order(void); +void test_read_switch_surface_order(void); diff --git a/include/freerdp/update.h b/include/freerdp/update.h index 17fe19abb..e31318bd0 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -24,17 +24,18 @@ /* Common */ -typedef struct +struct _BOUNDS { uint16 left; uint16 top; uint16 right; uint16 bottom; -} BOUNDS; +}; +typedef struct _BOUNDS BOUNDS; /* Bitmap Updates */ -typedef struct +struct _BITMAP_DATA { uint16 left; uint16 top; @@ -46,27 +47,30 @@ typedef struct uint16 flags; uint16 length; uint8* data; -} BITMAP_DATA; +}; +typedef struct _BITMAP_DATA BITMAP_DATA; -typedef struct +struct _BITMAP_UPDATE { uint16 number; BITMAP_DATA* bitmaps; -} BITMAP_UPDATE; +}; +typedef struct _BITMAP_UPDATE BITMAP_UPDATE; /* Palette Updates */ -typedef struct +struct _PALETTE_UPDATE { uint32 number; uint32 entries[256]; -} PALETTE_UPDATE; +}; +typedef struct _PALETTE_UPDATE PALETTE_UPDATE; /* Orders Updates */ /* Primary Drawing Orders */ -typedef struct +struct _ORDER_INFO { uint8 orderType; uint32 fieldFlags; @@ -79,18 +83,20 @@ typedef struct sint8 deltaBoundRight; sint8 deltaBoundBottom; boolean deltaCoordinates; -} ORDER_INFO; +}; +typedef struct _ORDER_INFO ORDER_INFO; -typedef struct +struct _DSTBLT_ORDER { sint16 nLeftRect; sint16 nTopRect; sint16 nWidth; sint16 nHeight; uint8 bRop; -} DSTBLT_ORDER; +}; +typedef struct _DSTBLT_ORDER DSTBLT_ORDER; -typedef struct +struct _PATBLT_ORDER { sint16 nLeftRect; sint16 nTopRect; @@ -104,9 +110,10 @@ typedef struct uint8 brushStyle; uint8 brushHatch; uint8 brushExtra[7]; -} PATBLT_ORDER; +}; +typedef struct _PATBLT_ORDER PATBLT_ORDER; -typedef struct +struct _SCRBLT_ORDER { sint16 nLeftRect; sint16 nTopRect; @@ -115,27 +122,30 @@ typedef struct uint8 bRop; sint16 nXSrc; sint16 nYSrc; -} SCRBLT_ORDER; +}; +typedef struct _SCRBLT_ORDER SCRBLT_ORDER; -typedef struct +struct _OPAQUE_RECT_ORDER { sint16 nLeftRect; sint16 nTopRect; sint16 nWidth; sint16 nHeight; uint32 color; -} OPAQUE_RECT_ORDER; +}; +typedef struct _OPAQUE_RECT_ORDER OPAQUE_RECT_ORDER; -typedef struct +struct _DRAW_NINE_GRID_ORDER { sint16 srcLeft; sint16 srcTop; sint16 srcRight; sint16 srcBottom; uint16 bitmapId; -} DRAW_NINE_GRID_ORDER; +}; +typedef struct _DRAW_NINE_GRID_ORDER DRAW_NINE_GRID_ORDER; -typedef struct +struct _MULTI_DSTBLT_ORDER { sint16 nLeftRect; sint16 nTopRect; @@ -145,9 +155,10 @@ typedef struct uint8 nDeltaEntries; uint16 cbData; uint8* codeDeltaList; -} MULTI_DSTBLT_ORDER; +}; +typedef struct _MULTI_DSTBLT_ORDER MULTI_DSTBLT_ORDER; -typedef struct +struct _MULTI_PATBLT_ORDER { sint16 nLeftRect; sint16 nTopRect; @@ -164,9 +175,10 @@ typedef struct uint8 nDeltaEntries; uint16 cbData; uint8* codeDeltaList; -} MULTI_PATBLT_ORDER; +}; +typedef struct _MULTI_PATBLT_ORDER MULTI_PATBLT_ORDER; -typedef struct +struct _MULTI_SCRBLT_ORDER { sint16 nLeftRect; sint16 nTopRect; @@ -178,17 +190,19 @@ typedef struct uint8 nDeltaEntries; uint16 cbData; uint8* codeDeltaList; -} MULTI_SCRBLT_ORDER; +}; +typedef struct _MULTI_SCRBLT_ORDER MULTI_SCRBLT_ORDER; -typedef struct +struct _DELTA_RECT { sint16 left; sint16 top; - sint16 right; - sint16 bottom; -} DELTA_RECT; + sint16 width; + sint16 height; +}; +typedef struct _DELTA_RECT DELTA_RECT; -typedef struct +struct _MULTI_OPAQUE_RECT_ORDER { sint16 nLeftRect; sint16 nTopRect; @@ -198,9 +212,10 @@ typedef struct uint8 numRectangles; uint16 cbData; DELTA_RECT rectangles[45]; -} MULTI_OPAQUE_RECT_ORDER; +}; +typedef struct _MULTI_OPAQUE_RECT_ORDER MULTI_OPAQUE_RECT_ORDER; -typedef struct +struct _MULTI_DRAW_NINE_GRID_ORDER { sint16 srcLeft; sint16 srcTop; @@ -210,9 +225,10 @@ typedef struct uint8 nDeltaEntries; uint16 cbData; uint8* codeDeltaList; -} MULTI_DRAW_NINE_GRID_ORDER; +}; +typedef struct _MULTI_DRAW_NINE_GRID_ORDER MULTI_DRAW_NINE_GRID_ORDER; -typedef struct +struct _LINE_TO_ORDER { uint16 backMode; sint16 nXStart; @@ -224,20 +240,29 @@ typedef struct uint8 penStyle; uint8 penWidth; uint32 penColor; -} LINE_TO_ORDER; +}; +typedef struct _LINE_TO_ORDER LINE_TO_ORDER; -typedef struct +struct _DELTA_POINT +{ + sint16 x; + sint16 y; +}; +typedef struct _DELTA_POINT DELTA_POINT; + +struct _POLYLINE_ORDER { sint16 xStart; sint16 yStart; uint8 bRop2; uint32 penColor; - uint8 nDeltaEntries; + uint8 numPoints; uint8 cbData; - uint8* codeDeltaList; -} POLYLINE_ORDER; + DELTA_POINT* points; +}; +typedef struct _POLYLINE_ORDER POLYLINE_ORDER; -typedef struct +struct _MEMBLT_ORDER { uint16 cacheId; sint16 nLeftRect; @@ -248,9 +273,10 @@ typedef struct sint16 nXSrc; sint16 nYSrc; uint16 cacheIndex; -} MEMBLT_ORDER; +}; +typedef struct _MEMBLT_ORDER MEMBLT_ORDER; -typedef struct +struct _MEM3BLT_ORDER { uint16 cacheId; sint16 nLeftRect; @@ -268,9 +294,10 @@ typedef struct uint8 brushHatch; uint8 brushExtra[7]; uint16 cacheIndex; -} MEM3BLT_ORDER; +}; +typedef struct _MEM3BLT_ORDER MEM3BLT_ORDER; -typedef struct +struct _SAVE_BITMAP_ORDER { uint32 savedBitmapPosition; sint16 nLeftRect; @@ -278,9 +305,10 @@ typedef struct sint16 nRightRect; sint16 nBottomRect; uint8 operation; -} SAVE_BITMAP_ORDER; +}; +typedef struct _SAVE_BITMAP_ORDER SAVE_BITMAP_ORDER; -typedef struct +struct _GLYPH_INDEX_ORDER { uint8 cacheId; uint8 flAccel; @@ -305,9 +333,10 @@ typedef struct sint16 y; uint8 cbData; uint8* data; -} GLYPH_INDEX_ORDER; +}; +typedef struct _GLYPH_INDEX_ORDER GLYPH_INDEX_ORDER; -typedef struct +struct _FAST_INDEX_ORDER { uint8 cacheId; uint8 flAccel; @@ -326,9 +355,10 @@ typedef struct sint16 y; uint8 cbData; uint8* data; -} FAST_INDEX_ORDER; +}; +typedef struct _FAST_INDEX_ORDER FAST_INDEX_ORDER; -typedef struct +struct _FAST_GLYPH_ORDER { uint8 cacheId; uint8 flAccel; @@ -347,9 +377,10 @@ typedef struct sint16 y; uint8 cbData; uint8* data; -} FAST_GLYPH_ORDER; +}; +typedef struct _FAST_GLYPH_ORDER FAST_GLYPH_ORDER; -typedef struct +struct _POLYGON_SC_ORDER { sint16 xStart; sint16 yStart; @@ -359,9 +390,10 @@ typedef struct uint8 nDeltaEntries; uint8 cbData; uint8* codeDeltaList; -} POLYGON_SC_ORDER; +}; +typedef struct _POLYGON_SC_ORDER POLYGON_SC_ORDER; -typedef struct +struct _POLYGON_CB_ORDER { sint16 xStart; sint16 yStart; @@ -377,9 +409,10 @@ typedef struct uint8 nDeltaEntries; uint8 cbData; uint8* codeDeltaList; -} POLYGON_CB_ORDER; +}; +typedef struct _POLYGON_CB_ORDER POLYGON_CB_ORDER; -typedef struct +struct _ELLIPSE_SC_ORDER { sint16 leftRect; sint16 topRect; @@ -388,9 +421,10 @@ typedef struct uint8 bRop2; uint8 fillMode; uint32 color; -} ELLIPSE_SC_ORDER; +}; +typedef struct _ELLIPSE_SC_ORDER ELLIPSE_SC_ORDER; -typedef struct +struct _ELLIPSE_CB_ORDER { sint16 leftRect; sint16 topRect; @@ -405,11 +439,12 @@ typedef struct uint8 brushStyle; uint8 brushHatch; uint8 brushExtra[7]; -} ELLIPSE_CB_ORDER; +}; +typedef struct _ELLIPSE_CB_ORDER ELLIPSE_CB_ORDER; /* Secondary Drawing Orders */ -typedef struct +struct _CACHE_BITMAP_ORDER { uint8 cacheId; uint8 bitmapBpp; @@ -419,9 +454,10 @@ typedef struct uint16 cacheIndex; uint8 bitmapComprHdr[8]; uint8* bitmapDataStream; -} CACHE_BITMAP_ORDER; +}; +typedef struct _CACHE_BITMAP_ORDER CACHE_BITMAP_ORDER; -typedef struct +struct _CACHE_BITMAP_V2_ORDER { uint8 cacheId; uint16 flags; @@ -434,9 +470,10 @@ typedef struct uint16 cacheIndex; uint8 bitmapComprHdr[8]; uint8* bitmapDataStream; -} CACHE_BITMAP_V2_ORDER; +}; +typedef struct _CACHE_BITMAP_V2_ORDER CACHE_BITMAP_V2_ORDER; -typedef struct +struct _BITMAP_DATA_EX { uint8 bpp; uint8 codecID; @@ -444,9 +481,10 @@ typedef struct uint16 height; uint32 length; uint8* data; -} BITMAP_DATA_EX; +}; +typedef struct _BITMAP_DATA_EX BITMAP_DATA_EX; -typedef struct +struct _CACHE_BITMAP_V3_ORDER { uint8 cacheId; uint8 bpp; @@ -455,16 +493,18 @@ typedef struct uint32 key1; uint32 key2; BITMAP_DATA_EX bitmapData; -} CACHE_BITMAP_V3_ORDER; +}; +typedef struct _CACHE_BITMAP_V3_ORDER CACHE_BITMAP_V3_ORDER; -typedef struct +struct _CACHE_COLOR_TABLE_ORDER { uint8 cacheIndex; uint16 numberColors; uint32* colorTable; -} CACHE_COLOR_TABLE_ORDER; +}; +typedef struct _CACHE_COLOR_TABLE_ORDER CACHE_COLOR_TABLE_ORDER; -typedef struct +struct _GLYPH_DATA { uint16 cacheIndex; uint16 x; @@ -473,17 +513,19 @@ typedef struct uint16 cy; uint16 cb; uint8* aj; -} GLYPH_DATA; +}; +typedef struct _GLYPH_DATA GLYPH_DATA; -typedef struct +struct _CACHE_GLYPH_ORDER { uint8 cacheId; uint8 cGlyphs; GLYPH_DATA* glyphData; uint8* unicodeCharacters; -} CACHE_GLYPH_ORDER; +}; +typedef struct _CACHE_GLYPH_ORDER CACHE_GLYPH_ORDER; -typedef struct +struct _GLYPH_DATA_V2 { uint8 cacheIndex; sint16 x; @@ -492,18 +534,20 @@ typedef struct uint16 cy; uint16 cb; uint8* aj; -} GLYPH_DATA_V2; +}; +typedef struct _GLYPH_DATA_V2 GLYPH_DATA_V2; -typedef struct +struct _CACHE_GLYPH_V2_ORDER { uint8 cacheId; uint8 flags; uint8 cGlyphs; GLYPH_DATA_V2* glyphData; uint8* unicodeCharacters; -} CACHE_GLYPH_V2_ORDER; +}; +typedef struct _CACHE_GLYPH_V2_ORDER CACHE_GLYPH_V2_ORDER; -typedef struct +struct _CACHE_BRUSH_ORDER { uint8 cacheEntry; uint8 bpp; @@ -512,30 +556,34 @@ typedef struct uint8 style; uint8 length; uint8* brushData; -} CACHE_BRUSH_ORDER; +}; +typedef struct _CACHE_BRUSH_ORDER CACHE_BRUSH_ORDER; /* Alternate Secondary Drawing Orders */ -typedef struct +struct _OFFSCREEN_DELETE_LIST { uint16 cIndices; uint16* indices; -} OFFSCREEN_DELETE_LIST; +}; +typedef struct _OFFSCREEN_DELETE_LIST OFFSCREEN_DELETE_LIST; -typedef struct +struct _CREATE_OFFSCREEN_BITMAP_ORDER { - uint16 offscreenBitmapId; + uint16 id; uint16 cx; uint16 cy; OFFSCREEN_DELETE_LIST deleteList; -} CREATE_OFFSCREEN_BITMAP_ORDER; +}; +typedef struct _CREATE_OFFSCREEN_BITMAP_ORDER CREATE_OFFSCREEN_BITMAP_ORDER; -typedef struct +struct _SWITCH_SURFACE_ORDER { uint16 bitmapId; -} SWITCH_SURFACE_ORDER; +}; +typedef struct _SWITCH_SURFACE_ORDER SWITCH_SURFACE_ORDER; -typedef struct +struct _NINE_GRID_BITMAP_INFO { uint32 flFlags; uint16 ulLeftWidth; @@ -543,23 +591,26 @@ typedef struct uint16 ulTopHeight; uint16 ulBottomHeight; uint32 crTransparent; -} NINE_GRID_BITMAP_INFO; +}; +typedef struct _NINE_GRID_BITMAP_INFO NINE_GRID_BITMAP_INFO; -typedef struct +struct _CREATE_NINE_GRID_BITMAP_ORDER { uint8 bitmapBpp; uint16 bitmapId; uint16 cx; uint16 cy; NINE_GRID_BITMAP_INFO nineGridInfo; -} CREATE_NINE_GRID_BITMAP_ORDER; +}; +typedef struct _CREATE_NINE_GRID_BITMAP_ORDER CREATE_NINE_GRID_BITMAP_ORDER; -typedef struct +struct _FRAME_MARKER_ORDER { uint32 action; -} FRAME_MARKER_ORDER; +}; +typedef struct _FRAME_MARKER_ORDER FRAME_MARKER_ORDER; -typedef struct +struct _STREAM_BITMAP_FIRST_ORDER { uint8 bitmapFlags; uint8 bitmapBpp; @@ -569,39 +620,44 @@ typedef struct uint32 bitmapSize; uint16 bitmapBlockSize; uint8* bitmapBlock; -} STREAM_BITMAP_FIRST_ORDER; +}; +typedef struct _STREAM_BITMAP_FIRST_ORDER STREAM_BITMAP_FIRST_ORDER; -typedef struct +struct _STREAM_BITMAP_NEXT_ORDER { uint8 bitmapFlags; uint16 bitmapType; uint16 bitmapBlockSize; uint8* bitmapBlock; -} STREAM_BITMAP_NEXT_ORDER; +}; +typedef struct _STREAM_BITMAP_NEXT_ORDER STREAM_BITMAP_NEXT_ORDER; -typedef struct +struct _DRAW_GDIPLUS_FIRST_ORDER { uint16 cbSize; uint32 cbTotalSize; uint32 cbTotalEmfSize; uint8* emfRecords; -} DRAW_GDIPLUS_FIRST_ORDER; +}; +typedef struct _DRAW_GDIPLUS_FIRST_ORDER DRAW_GDIPLUS_FIRST_ORDER; -typedef struct +struct _DRAW_GDIPLUS_NEXT_ORDER { uint16 cbSize; uint8* emfRecords; -} DRAW_GDIPLUS_NEXT_ORDER; +}; +typedef struct _DRAW_GDIPLUS_NEXT_ORDER DRAW_GDIPLUS_NEXT_ORDER; -typedef struct +struct _DRAW_GDIPLUS_END_ORDER { uint16 cbSize; uint32 cbTotalSize; uint32 cbTotalEmfSize; uint8* emfRecords; -} DRAW_GDIPLUS_END_ORDER; +}; +typedef struct _DRAW_GDIPLUS_END_ORDER DRAW_GDIPLUS_END_ORDER; -typedef struct +struct _DRAW_GDIPLUS_CACHE_FIRST_ORDER { uint8 flags; uint16 cacheType; @@ -609,18 +665,20 @@ typedef struct uint16 cbSize; uint32 cbTotalSize; uint8* emfRecords; -} DRAW_GDIPLUS_CACHE_FIRST_ORDER; +}; +typedef struct _DRAW_GDIPLUS_CACHE_FIRST_ORDER DRAW_GDIPLUS_CACHE_FIRST_ORDER; -typedef struct +struct _DRAW_GDIPLUS_CACHE_NEXT_ORDER { uint8 flags; uint16 cacheType; uint16 cacheIndex; uint16 cbSize; uint8* emfRecords; -} DRAW_GDIPLUS_CACHE_NEXT_ORDER; +}; +typedef struct _DRAW_GDIPLUS_CACHE_NEXT_ORDER DRAW_GDIPLUS_CACHE_NEXT_ORDER; -typedef struct +struct _DRAW_GDIPLUS_CACHE_END_ORDER { uint8 flags; uint16 cacheType; @@ -628,7 +686,8 @@ typedef struct uint16 cbSize; uint32 cbTotalSize; uint8* emfRecords; -} DRAW_GDIPLUS_CACHE_END_ORDER; +}; +typedef struct _DRAW_GDIPLUS_CACHE_END_ORDER DRAW_GDIPLUS_CACHE_END_ORDER; /* Constants */ diff --git a/libfreerdp-core/orders.c b/libfreerdp-core/orders.c index 7a068d946..5090d0a60 100644 --- a/libfreerdp-core/orders.c +++ b/libfreerdp-core/orders.c @@ -205,15 +205,12 @@ void update_read_2byte_signed(STREAM* s, sint16* value) negative = (byte & 0x40) ? True : False; + *value = (byte & 0x3F); + if (byte & 0x80) { - *value = (byte & 0x3F) << 8; stream_read_uint8(s, byte); - *value |= byte; - } - else - { - *value = (byte & 0x3F); + *value = (*value << 8) | byte; } if (negative) @@ -264,6 +261,107 @@ void update_read_4byte_unsigned(STREAM* s, uint32* value) } } +void update_read_delta(STREAM* s, sint16* value) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte & 0x40) + *value = (byte | ~0x3F); + else + *value = (byte & 0x3F); + + if (byte & 0x80) + { + stream_read_uint8(s, byte); + *value = (*value << 8) | byte; + } +} + +void update_read_delta_rects(STREAM* s, DELTA_RECT* rectangles, int number) +{ + int i; + uint8 flags; + uint8* zeroBits; + int zeroBitsSize; + + if (number > 45) + number = 45; + + zeroBitsSize = ((number + 1) / 2); + + stream_get_mark(s, zeroBits); + stream_seek(s, zeroBitsSize); + + memset(rectangles, 0, sizeof(DELTA_RECT) * number); + + for (i = 1; i < number + 1; i++) + { + if ((i - 1) % 2 == 0) + flags = zeroBits[(i - 1) / 2]; + + if (~flags & 0x80) + update_read_delta(s, &rectangles[i].left); + + if (~flags & 0x40) + update_read_delta(s, &rectangles[i].top); + + if (~flags & 0x20) + update_read_delta(s, &rectangles[i].width); + else + rectangles[i].width = rectangles[i - 1].width; + + if (~flags & 0x10) + update_read_delta(s, &rectangles[i].height); + else + rectangles[i].height = rectangles[i - 1].height; + + rectangles[i].left = rectangles[i].left + rectangles[i - 1].left; + rectangles[i].top = rectangles[i].top + rectangles[i - 1].top; + + flags <<= 4; + } +} + +void update_read_delta_points(STREAM* s, DELTA_POINT* points, int number, sint16 x, sint16 y) +{ + int i; + uint8 flags; + uint8* zeroBits; + int zeroBitsSize; + + zeroBitsSize = ((number + 3) / 4); + + stream_get_mark(s, zeroBits); + stream_seek(s, zeroBitsSize); + + memset(points, 0, sizeof(DELTA_POINT) * number); + + for (i = 1; i < number + 1; i++) + { + if ((i - 1) % 4 == 0) + flags = zeroBits[(i - 1) / 4]; + + if (~flags & 0x80) + update_read_delta(s, &points[i].x); + + if (~flags & 0x40) + update_read_delta(s, &points[i].y); + + points[i].x = points[i].x + points[i - 1].x; + points[i].y = points[i].y + points[i - 1].y; + + points[i - 1].x += x; + points[i - 1].y += y; + + flags <<= 2; + } + + points[i - 1].x += x; + points[i - 1].y += y; +} + /* Primary Drawing Orders */ void update_read_dstblt_order(STREAM* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt) @@ -549,43 +647,8 @@ void update_read_multi_opaque_rect_order(STREAM* s, ORDER_INFO* orderInfo, MULTI if (orderInfo->fieldFlags & ORDER_FIELD_09) { - int i; - uint8 flags; - uint8* zeroBits; - int zeroBitsSize; - DELTA_RECT* rectangles; - - rectangles = multi_opaque_rect->rectangles; - zeroBitsSize = ((multi_opaque_rect->numRectangles + 1) / 2); - stream_read_uint16(s, multi_opaque_rect->cbData); - - stream_get_mark(s, zeroBits); - stream_seek(s, zeroBitsSize); - - memset(&rectangles[0], 0, sizeof(DELTA_RECT)); - - for (i = 0; i < multi_opaque_rect->numRectangles; i++) - { - flags = zeroBits[i / 2]; - - if (i % 2 == 0) - flags = (flags >> 4) & 0x0F; - else - flags = flags & 0x0F; - - if (~flags & 0x80) - update_read_2byte_signed(s, &rectangles[i].left); - - if (~flags & 0x40); - update_read_2byte_signed(s, &rectangles[i].top); - - if (~flags & 0x20); - update_read_2byte_signed(s, &rectangles[i].right); - - if (~flags & 0x10); - update_read_2byte_signed(s, &rectangles[i].bottom); - } + update_read_delta_rects(s, multi_opaque_rect->rectangles, multi_opaque_rect->numRectangles); } } @@ -661,15 +724,24 @@ void update_read_polyline_order(STREAM* s, ORDER_INFO* orderInfo, POLYLINE_ORDER stream_read_uint8(s, polyline->bRop2); if (orderInfo->fieldFlags & ORDER_FIELD_04) - update_read_color(s, &polyline->penColor); + stream_seek_uint16(s); if (orderInfo->fieldFlags & ORDER_FIELD_05) - stream_read_uint8(s, polyline->nDeltaEntries); + update_read_color(s, &polyline->penColor); if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, polyline->numPoints); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) { stream_read_uint8(s, polyline->cbData); - stream_seek(s, polyline->cbData); + + if (polyline->points == NULL) + polyline->points = (DELTA_POINT*) xmalloc(polyline->cbData); + else + polyline->points = (DELTA_POINT*) xrealloc(polyline->points, polyline->cbData); + + update_read_delta_points(s, polyline->points, polyline->numPoints, polyline->xStart, polyline->yStart); } } @@ -1337,7 +1409,7 @@ void update_read_create_offscreen_bitmap_order(STREAM* s, CREATE_OFFSCREEN_BITMA boolean deleteListPresent; stream_read_uint16(s, flags); /* flags (2 bytes) */ - create_offscreen_bitmap->offscreenBitmapId = flags & 0x7FFF; + create_offscreen_bitmap->id = flags & 0x7FFF; deleteListPresent = (flags & 0x8000) ? True : False; stream_read_uint16(s, create_offscreen_bitmap->cx); /* cx (2 bytes) */ diff --git a/libfreerdp-gdi/gdi.c b/libfreerdp-gdi/gdi.c index 3e5972bf4..a9ac1c572 100644 --- a/libfreerdp-gdi/gdi.c +++ b/libfreerdp-gdi/gdi.c @@ -1198,10 +1198,8 @@ void gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_opa { rectangle = &multi_opaque_rect->rectangles[i]; - rect.left = rectangle->left; - rect.top = rectangle->top; - rect.right = rectangle->right; - rect.bottom = rectangle->bottom; + gdi_CRgnToRect(rectangle->left, rectangle->top, + rectangle->width, rectangle->height, &rect); brush_color = gdi_color_convert(multi_opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv);