I've got another missing capability to work: MultiPatBlt ([MS-RDPEGDI] 
2.2.2.2.1.1.2.4)

Follows a patch for those who may want to validate it. Can someone please do 
some tests and check if it is alright to commit?

Thanks

Eduardo Fiss Beloni
bel...@ossystems.com.br
55 53 8117 8244


      
From 7b2c516c06a3c8c28338049a52d7e44411281eca Mon Sep 17 00:00:00 2001
From: Eduardo Beloni <bel...@ossystems.com.br>
Date: Fri, 4 Feb 2011 18:09:27 -0200
Subject: [PATCH] libfreerdp: implement MuiltPatBlt

---
 libfreerdp/capabilities.c |    2 +-
 libfreerdp/orders.c       |  105 +++++++++++++++++++++++++++++++++++++++++++++
 libfreerdp/orderstypes.h  |   21 ++++++++-
 libfreerdp/types.h        |    5 ++
 4 files changed, 130 insertions(+), 3 deletions(-)

diff --git a/libfreerdp/capabilities.c b/libfreerdp/capabilities.c
index 2d45cbb..72d0617 100644
--- a/libfreerdp/capabilities.c
+++ b/libfreerdp/capabilities.c
@@ -188,7 +188,7 @@ rdp_out_order_capset(rdpRdp * rdp, STREAM s)
 	orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = 1;
 	orderSupport[NEG_SAVEBITMAP_INDEX] = (rdp->settings->desktop_save ? 1 : 0);
 	// orderSupport[NEG_MULTIDSTBLT_INDEX] = 1;
-	// orderSupport[NEG_MULTIPATBLT_INDEX] = 1;
+	orderSupport[NEG_MULTIPATBLT_INDEX] = 1;
 	// orderSupport[NEG_MULTISCRBLT_INDEX] = 1;
 	// orderSupport[NEG_MULTIOPAQUERECT_INDEX] = 1;
 	orderSupport[NEG_FAST_INDEX_INDEX] = 1;
diff --git a/libfreerdp/orders.c b/libfreerdp/orders.c
index b73637a..4433a47 100644
--- a/libfreerdp/orders.c
+++ b/libfreerdp/orders.c
@@ -265,6 +265,106 @@ process_patblt(rdpOrders * orders, STREAM s, PATBLT_ORDER * os, uint32 present,
 		  &brush, os->bgcolor, os->fgcolor);
 }
 
+/* Process a multi pattern blt order */
+static void
+process_multipatblt(rdpOrders * orders, STREAM s, MULTIPATBLT_ORDER * os, uint32 present, RD_BOOL delta)
+{
+	RD_BRUSH brush;
+	int size;
+	int index, data, next;
+	int x, y, w = 0, h = 0;
+	uint8 flags = 0;
+	RECTANGLE *rects;
+
+	if (present & 0x0001)
+		rdp_in_coord(s, &os->x, delta);
+
+	if (present & 0x0002)
+		rdp_in_coord(s, &os->y, delta);
+
+	if (present & 0x0004)
+		rdp_in_coord(s, &os->cx, delta);
+
+	if (present & 0x0008)
+		rdp_in_coord(s, &os->cy, delta);
+
+	if (present & 0x0010)
+		in_uint8(s, os->opcode);
+
+	if (present & 0x0020)
+		rdp_in_color(s, &os->bgcolor);
+
+	if (present & 0x0040)
+		rdp_in_color(s, &os->fgcolor);
+
+	rdp_parse_brush(s, &os->brush, present >> 7);
+
+	if (present & 0x1000)
+		in_uint8(s, os->nentries);
+
+	if (present & 0x2000)
+	{
+		in_uint16_le(s, os->datasize);
+		in_uint8a(s, os->data, os->datasize);
+	}
+
+	printf("MULTIPATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,n=%d)\n",
+	      os->opcode, os->x, os->y, os->cx, os->cy, os->nentries);
+
+	setup_brush(orders, &brush, &os->brush);
+
+	size = (os->nentries + 1) * sizeof(RECTANGLE);
+	if (size > orders->buffer_size)
+	{
+		orders->buffer = xrealloc(orders->buffer, size);
+		orders->buffer_size = size;
+	}
+
+	rects = (RECTANGLE *) orders->buffer;
+	memset(rects, 0, size);
+
+	index = 0;
+	data = ((os->nentries - 1) / 8) + 1;
+	for (next = 1; (next <= os->nentries) && (next <= 45) && (data < os->datasize); next++)
+	{
+		if ((next - 1) % 8 == 0)
+			flags = os->data[index++];
+
+		if (~flags & 0x80)
+			rects[next].l = parse_delta(os->data, &data);
+		else
+			rects[next].l = rects[next - 1].l;
+
+		if (~flags & 0x40)
+			rects[next].t = parse_delta(os->data, &data);
+		else
+			rects[next].t = rects[next - 1].t;
+
+		if (~flags & 0x20)
+			rects[next].r = parse_delta(os->data, &data);
+		else
+			rects[next].r = rects[next - 1].r;
+
+		if (~flags & 0x10)
+			rects[next].b = parse_delta(os->data, &data);
+		else
+			rects[next].b = rects[next - 1].b;
+
+		x = os->x + rects[next].l - rects[next - 1].l;
+		y = os->y + rects[next].t - rects[next - 1].t;
+
+/* I can't explain why the following code makes things go wrong... */
+/*		w = os->cx + rects[next].r - rects[next].l;*/
+/*		h = os->cy + rects[next].b - rects[next].t;*/
+
+		printf("rect (%d, %d, %d, %d)\n", x, y, w, h);
+
+		flags <<= 4;
+
+		ui_patblt(orders->rdp->inst, os->opcode, x, y, w, h, &brush, os->bgcolor, os->fgcolor);
+	}
+}
+
 /* Process a screen blt order */
 static void
 process_scrblt(rdpOrders * orders, STREAM s, SCRBLT_ORDER * os, uint32 present, RD_BOOL delta)
@@ -1735,6 +1835,7 @@ process_orders(rdpOrders * orders, STREAM s, uint16 num_orders)
 					break;
 
 				case RDP_ORDER_PATBLT:
+				case RDP_ORDER_MULTIPATBLT:
 				case RDP_ORDER_MEMBLT:
 				case RDP_ORDER_LINETO:
 				case RDP_ORDER_POLYGON_CB:
@@ -1773,6 +1874,10 @@ process_orders(rdpOrders * orders, STREAM s, uint16 num_orders)
 					process_patblt(orders, s, &os->patblt, present, delta);
 					break;
 
+				case RDP_ORDER_MULTIPATBLT:
+					process_multipatblt(orders, s, &os->multipatblt, present, delta);
+					break;
+
 				case RDP_ORDER_SCRBLT:
 					process_scrblt(orders, s, &os->scrblt, present, delta);
 					break;
diff --git a/libfreerdp/orderstypes.h b/libfreerdp/orderstypes.h
index fe00ce3..537f36b 100644
--- a/libfreerdp/orderstypes.h
+++ b/libfreerdp/orderstypes.h
@@ -32,6 +32,8 @@
 #define RDP_ORDER_SMALL      0x40
 #define RDP_ORDER_TINY       0x80
 
+#define MAX_DATA 256
+
 /* Primary Drawing Orders */
 enum RDP_ORDER_TYPE
 {
@@ -114,6 +116,22 @@ typedef struct _PATBLT_ORDER
 }
 PATBLT_ORDER;
 
+typedef struct _MULTIPATBLT_ORDER
+{
+	sint16 x;
+	sint16 y;
+	sint16 cx;
+	sint16 cy;
+	uint8 opcode;
+	uint32 bgcolor;
+	uint32 fgcolor;
+	RD_BRUSH brush;
+	uint8 nentries;
+	uint16 datasize;
+	uint8 data[MAX_DATA];
+}
+MULTIPATBLT_ORDER;
+
 typedef struct _SCRBLT_ORDER
 {
 	sint16 x;
@@ -200,8 +218,6 @@ typedef struct _MEMBLT_ORDER
 }
 MEMBLT_ORDER;
 
-#define MAX_DATA 256
-
 typedef struct _POLYGON_SC_ORDER
 {
 	sint16 x;
@@ -330,6 +346,7 @@ typedef struct _RDP_ORDER_STATE
 
 	DSTBLT_ORDER dstblt;
 	PATBLT_ORDER patblt;
+	MULTIPATBLT_ORDER multipatblt;
 	SCRBLT_ORDER scrblt;
 	LINETO_ORDER lineto;
 	OPAQUERECT_ORDER opaquerect;
diff --git a/libfreerdp/types.h b/libfreerdp/types.h
index a52a888..d82078e 100644
--- a/libfreerdp/types.h
+++ b/libfreerdp/types.h
@@ -85,4 +85,9 @@ typedef struct _RDPCOMP
 	struct stream ns;
 } RDPCOMP;
 
+typedef struct RECTANGLE
+{
+	sint16 l, t, r, b;
+} RECTANGLE;
+
 #endif // __TYPES_H
-- 
1.6.6.1

------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Freerdp-devel mailing list
Freerdp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freerdp-devel

Reply via email to