diff options
Diffstat (limited to 'xrdp/xrdp_orders.c')
-rw-r--r-- | xrdp/xrdp_orders.c | 569 |
1 files changed, 465 insertions, 104 deletions
diff --git a/xrdp/xrdp_orders.c b/xrdp/xrdp_orders.c index d49ce630..aeb10bb2 100644 --- a/xrdp/xrdp_orders.c +++ b/xrdp/xrdp_orders.c @@ -52,7 +52,9 @@ int xrdp_orders_init(struct xrdp_orders* self) self->order_count = 0; /* is this big enough */ if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0) + { return 1; + } out_uint16_le(self->out_s, RDP_UPDATE_ORDERS); out_uint8s(self->out_s, 2); /* pad */ self->order_count_ptr = self->out_s->p; @@ -79,7 +81,9 @@ int xrdp_orders_send(struct xrdp_orders* self) self->order_count_ptr[1] = self->order_count >> 8; if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, RDP_DATA_PDU_UPDATE) != 0) + { rv = 1; + } } } return rv; @@ -96,7 +100,9 @@ int xrdp_orders_force_send(struct xrdp_orders* self) self->order_count_ptr[1] = self->order_count >> 8; if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, RDP_DATA_PDU_UPDATE) != 0) + { return 1; + } } self->order_count = 0; self->order_level = 0; @@ -114,13 +120,19 @@ int xrdp_orders_check(struct xrdp_orders* self, int max_size) if (self->order_level < 1) { if (max_size > 8000) + { return 1; + } else + { return 0; + } } size = self->out_s->p - self->order_count_ptr; if (size < 0 || size > 8192) + { return 1; + } if (size + max_size + 100 > 8000) { xrdp_orders_force_send(self); @@ -136,10 +148,16 @@ int xrdp_orders_last_bounds(struct xrdp_orders* self, struct xrdp_rect* rect) { if (rect == 0) + { return 0; - if (rect->left == self->clip_left && rect->top == self->clip_top && - rect->right == self->clip_right && rect->bottom == self->clip_bottom) + } + if (rect->left == self->clip_left && + rect->top == self->clip_top && + rect->right == self->clip_right && + rect->bottom == self->clip_bottom) + { return 1; + } return 0; } @@ -151,8 +169,12 @@ int xrdp_orders_send_delta(struct xrdp_orders* self, int* vals, int count) int i; for (i = 0; i < count; i += 2) + { if (g_abs(vals[i] - vals[i + 1]) >= 128) + { return 0; + } + } return 1; } @@ -167,52 +189,92 @@ int xrdp_orders_out_bounds(struct xrdp_orders* self, struct xrdp_rect* rect) bounds_flags_ptr = self->out_s->p; out_uint8s(self->out_s, 1); /* left */ - if (rect->left == self->clip_left) ; + if (rect->left == self->clip_left) + { + } else if (g_abs(rect->left - self->clip_left) < 128) + { bounds_flags |= 0x10; + } else + { bounds_flags |= 0x01; + } /* top */ - if (rect->top == self->clip_top) ; + if (rect->top == self->clip_top) + { + } else if (g_abs(rect->top - self->clip_top) < 128) + { bounds_flags |= 0x20; + } else + { bounds_flags |= 0x02; + } /* right */ - if (rect->right == self->clip_right) ; + if (rect->right == self->clip_right) + { + } else if (g_abs(rect->right - self->clip_right) < 128) + { bounds_flags |= 0x40; + } else + { bounds_flags |= 0x04; + } /* bottom */ - if (rect->bottom == self->clip_bottom) ; + if (rect->bottom == self->clip_bottom) + { + } else if (g_abs(rect->bottom - self->clip_bottom) < 128) + { bounds_flags |= 0x80; + } else + { bounds_flags |= 0x08; + } /* left */ if (bounds_flags & 0x01) - out_uint16_le(self->out_s, rect->left) + { + out_uint16_le(self->out_s, rect->left); + } else if (bounds_flags & 0x10) - out_uint8(self->out_s, rect->left - self->clip_left) + { + out_uint8(self->out_s, rect->left - self->clip_left); + } self->clip_left = rect->left; /* top */ if (bounds_flags & 0x02) - out_uint16_le(self->out_s, rect->top) + { + out_uint16_le(self->out_s, rect->top); + } else if (bounds_flags & 0x20) - out_uint8(self->out_s, rect->top - self->clip_top) + { + out_uint8(self->out_s, rect->top - self->clip_top); + } self->clip_top = rect->top; /* right */ if (bounds_flags & 0x04) - out_uint16_le(self->out_s, rect->right) + { + out_uint16_le(self->out_s, rect->right); + } else if (bounds_flags & 0x40) - out_uint8(self->out_s, rect->right - self->clip_right) + { + out_uint8(self->out_s, rect->right - self->clip_right); + } self->clip_right = rect->right; /* bottom */ if (bounds_flags & 0x08) - out_uint16_le(self->out_s, rect->bottom) + { + out_uint16_le(self->out_s, rect->bottom); + } else if (bounds_flags & 0x80) - out_uint8(self->out_s, rect->bottom - self->clip_bottom) + { + out_uint8(self->out_s, rect->bottom - self->clip_bottom); + } self->clip_bottom = rect->bottom; /* set flags */ *bounds_flags_ptr = bounds_flags; @@ -235,63 +297,93 @@ int xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy, self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->last_order != RDP_ORDER_RECT) + { order_flags |= RDP_ORDER_CHANGE; + } self->last_order = RDP_ORDER_RECT; if (rect != 0) { order_flags |= RDP_ORDER_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) + { order_flags |= RDP_ORDER_LASTBOUNDS; + } } - vals[0] = x; vals[1] = self->rect_x; - vals[2] = y; vals[3] = self->rect_y; - vals[4] = cx; vals[5] = self->rect_cx; - vals[6] = cy; vals[7] = self->rect_cy; + vals[0] = x; + vals[1] = self->rect_x; + vals[2] = y; + vals[3] = self->rect_y; + vals[4] = cx; + vals[5] = self->rect_cx; + vals[6] = cy; + vals[7] = self->rect_cy; if (xrdp_orders_send_delta(self, vals, 8)) + { order_flags |= RDP_ORDER_DELTA; + } out_uint8(self->out_s, order_flags) if (order_flags & RDP_ORDER_CHANGE) - out_uint8(self->out_s, self->last_order) + { + out_uint8(self->out_s, self->last_order); + } present = 0; present_ptr = self->out_s->p; /* hold 1 byte present pointer */ out_uint8s(self->out_s, 1) if ((order_flags & RDP_ORDER_BOUNDS) && !(order_flags & RDP_ORDER_LASTBOUNDS)) + { xrdp_orders_out_bounds(self, rect); + } if (x != self->rect_x) { present |= 0x01; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, x - self->rect_x) + { + out_uint8(self->out_s, x - self->rect_x); + } else - out_uint16_le(self->out_s, x) + { + out_uint16_le(self->out_s, x); + } self->rect_x = x; } if (y != self->rect_y) { present |= 0x02; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, y - self->rect_y) + { + out_uint8(self->out_s, y - self->rect_y); + } else - out_uint16_le(self->out_s, y) + { + out_uint16_le(self->out_s, y); + } self->rect_y = y; } if (cx != self->rect_cx) { present |= 0x04; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cx - self->rect_cx) + { + out_uint8(self->out_s, cx - self->rect_cx); + } else - out_uint16_le(self->out_s, cx) + { + out_uint16_le(self->out_s, cx); + } self->rect_cx = cx; } if (cy != self->rect_cy) { present |= 0x08; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cy - self->rect_cy) + { + out_uint8(self->out_s, cy - self->rect_cy); + } else - out_uint16_le(self->out_s, cy) + { + out_uint16_le(self->out_s, cy); + } self->rect_cy = cy; } if ((color & 0xff) != (self->rect_color & 0xff)) @@ -333,65 +425,97 @@ int xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y, self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->last_order != RDP_ORDER_SCREENBLT) + { order_flags |= RDP_ORDER_CHANGE; + } self->last_order = RDP_ORDER_SCREENBLT; if (rect != 0) { order_flags |= RDP_ORDER_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) + { order_flags |= RDP_ORDER_LASTBOUNDS; + } } - vals[0] = x; vals[1] = self->scr_blt_x; - vals[2] = y; vals[3] = self->scr_blt_y; - vals[4] = cx; vals[5] = self->scr_blt_cx; - vals[6] = cy; vals[7] = self->scr_blt_cy; - vals[8] = srcx; vals[9] = self->scr_blt_srcx; - vals[10] = srcy; vals[11] = self->scr_blt_srcy; + vals[0] = x; + vals[1] = self->scr_blt_x; + vals[2] = y; + vals[3] = self->scr_blt_y; + vals[4] = cx; + vals[5] = self->scr_blt_cx; + vals[6] = cy; + vals[7] = self->scr_blt_cy; + vals[8] = srcx; + vals[9] = self->scr_blt_srcx; + vals[10] = srcy; + vals[11] = self->scr_blt_srcy; if (xrdp_orders_send_delta(self, vals, 12)) + { order_flags |= RDP_ORDER_DELTA; + } out_uint8(self->out_s, order_flags); if (order_flags & RDP_ORDER_CHANGE) - out_uint8(self->out_s, self->last_order) + { + out_uint8(self->out_s, self->last_order); + } present = 0; present_ptr = self->out_s->p; /* hold 1 byte present pointer */ out_uint8s(self->out_s, 1) if ((order_flags & RDP_ORDER_BOUNDS) && !(order_flags & RDP_ORDER_LASTBOUNDS)) + { xrdp_orders_out_bounds(self, rect); + } if (x != self->scr_blt_x) { present |= 0x01; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, x - self->scr_blt_x) + { + out_uint8(self->out_s, x - self->scr_blt_x); + } else - out_uint16_le(self->out_s, x) + { + out_uint16_le(self->out_s, x); + } self->scr_blt_x = x; } if (y != self->scr_blt_y) { present |= 0x02; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, y - self->scr_blt_y) + { + out_uint8(self->out_s, y - self->scr_blt_y); + } else - out_uint16_le(self->out_s, y) + { + out_uint16_le(self->out_s, y); + } self->scr_blt_y = y; } if (cx != self->scr_blt_cx) { present |= 0x04; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cx - self->scr_blt_cx) + { + out_uint8(self->out_s, cx - self->scr_blt_cx); + } else - out_uint16_le(self->out_s, cx) + { + out_uint16_le(self->out_s, cx); + } self->scr_blt_cx = cx; } if (cy != self->scr_blt_cy) { present |= 0x08; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cy - self->scr_blt_cy) + { + out_uint8(self->out_s, cy - self->scr_blt_cy); + } else - out_uint16_le(self->out_s, cy) + { + out_uint16_le(self->out_s, cy); + } self->scr_blt_cy = cy; } if (rop != self->scr_blt_rop) @@ -404,18 +528,26 @@ int xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y, { present |= 0x20; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, srcx - self->scr_blt_srcx) + { + out_uint8(self->out_s, srcx - self->scr_blt_srcx); + } else - out_uint16_le(self->out_s, srcx) + { + out_uint16_le(self->out_s, srcx); + } self->scr_blt_srcx = srcx; } if (srcy != self->scr_blt_srcy) { present |= 0x40; if (order_flags & RDP_ORDER_DELTA) + { out_uint8(self->out_s, srcy - self->scr_blt_srcy) + } else + { out_uint16_le(self->out_s, srcy) + } self->scr_blt_srcy = srcy; } present_ptr[0] = present; @@ -441,64 +573,94 @@ int xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y, self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->last_order != RDP_ORDER_PATBLT) + { order_flags |= RDP_ORDER_CHANGE; + } self->last_order = RDP_ORDER_PATBLT; if (rect != 0) { order_flags |= RDP_ORDER_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) + { order_flags |= RDP_ORDER_LASTBOUNDS; + } } - vals[0] = x; vals[1] = self->pat_blt_x; - vals[2] = y; vals[3] = self->pat_blt_y; - vals[4] = cx; vals[5] = self->pat_blt_cx; - vals[6] = cy; vals[7] = self->pat_blt_cy; + vals[0] = x; + vals[1] = self->pat_blt_x; + vals[2] = y; + vals[3] = self->pat_blt_y; + vals[4] = cx; + vals[5] = self->pat_blt_cx; + vals[6] = cy; + vals[7] = self->pat_blt_cy; if (xrdp_orders_send_delta(self, vals, 8)) + { order_flags |= RDP_ORDER_DELTA; + } out_uint8(self->out_s, order_flags); if (order_flags & RDP_ORDER_CHANGE) - out_uint8(self->out_s, self->last_order) + { + out_uint8(self->out_s, self->last_order); + } present = 0; present_ptr = self->out_s->p; /* hold 2 byte present pointer, todo */ out_uint8s(self->out_s, 2) /* this can be smaller, */ /* see RDP_ORDER_SMALL and RDP_ORDER_TINY */ if ((order_flags & RDP_ORDER_BOUNDS) && !(order_flags & RDP_ORDER_LASTBOUNDS)) + { xrdp_orders_out_bounds(self, rect); + } if (x != self->pat_blt_x) { present |= 0x0001; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, x - self->pat_blt_x) + { + out_uint8(self->out_s, x - self->pat_blt_x); + } else - out_uint16_le(self->out_s, x) + { + out_uint16_le(self->out_s, x); + } self->pat_blt_x = x; } if (y != self->pat_blt_y) { present |= 0x0002; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, y - self->pat_blt_y) + { + out_uint8(self->out_s, y - self->pat_blt_y); + } else - out_uint16_le(self->out_s, y) + { + out_uint16_le(self->out_s, y); + } self->pat_blt_y = y; } if (cx != self->pat_blt_cx) { present |= 0x0004; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cx - self->pat_blt_cx) + { + out_uint8(self->out_s, cx - self->pat_blt_cx); + } else - out_uint16_le(self->out_s, cx) + { + out_uint16_le(self->out_s, cx); + } self->pat_blt_cx = cx; } if (cy != self->pat_blt_cy) { present |= 0x0008; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cy - self->pat_blt_cy) + { + out_uint8(self->out_s, cy - self->pat_blt_cy); + } else - out_uint16_le(self->out_s, cy) + { + out_uint16_le(self->out_s, cy); + } self->pat_blt_cy = cy; } if (rop != self->pat_blt_rop) @@ -581,63 +743,93 @@ int xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y, self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->last_order != RDP_ORDER_DESTBLT) + { order_flags |= RDP_ORDER_CHANGE; + } self->last_order = RDP_ORDER_DESTBLT; if (rect != 0) { order_flags |= RDP_ORDER_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) + { order_flags |= RDP_ORDER_LASTBOUNDS; + } } - vals[0] = x; vals[1] = self->dest_blt_x; - vals[2] = y; vals[3] = self->dest_blt_y; - vals[4] = cx; vals[5] = self->dest_blt_cx; - vals[6] = cy; vals[7] = self->dest_blt_cy; + vals[0] = x; + vals[1] = self->dest_blt_x; + vals[2] = y; + vals[3] = self->dest_blt_y; + vals[4] = cx; + vals[5] = self->dest_blt_cx; + vals[6] = cy; + vals[7] = self->dest_blt_cy; if (xrdp_orders_send_delta(self, vals, 8)) + { order_flags |= RDP_ORDER_DELTA; + } out_uint8(self->out_s, order_flags); if (order_flags & RDP_ORDER_CHANGE) + { out_uint8(self->out_s, self->last_order) + } present = 0; present_ptr = self->out_s->p; /* hold 1 byte present pointer */ out_uint8s(self->out_s, 1) if ((order_flags & RDP_ORDER_BOUNDS) && !(order_flags & RDP_ORDER_LASTBOUNDS)) + { xrdp_orders_out_bounds(self, rect); + } if (x != self->dest_blt_x) { present |= 0x01; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, x - self->dest_blt_x) + { + out_uint8(self->out_s, x - self->dest_blt_x); + } else - out_uint16_le(self->out_s, x) + { + out_uint16_le(self->out_s, x); + } self->dest_blt_x = x; } if (y != self->dest_blt_y) { present |= 0x02; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, y - self->dest_blt_y) + { + out_uint8(self->out_s, y - self->dest_blt_y); + } else - out_uint16_le(self->out_s, y) + { + out_uint16_le(self->out_s, y); + } self->dest_blt_y = y; } if (cx != self->dest_blt_cx) { present |= 0x04; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cx - self->dest_blt_cx) + { + out_uint8(self->out_s, cx - self->dest_blt_cx); + } else - out_uint16_le(self->out_s, cx) + { + out_uint16_le(self->out_s, cx); + } self->dest_blt_cx = cx; } if (cy != self->dest_blt_cy) { present |= 0x08; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cy - self->dest_blt_cy) + { + out_uint8(self->out_s, cy - self->dest_blt_cy); + } else - out_uint16_le(self->out_s, cy) + { + out_uint16_le(self->out_s, cy); + } self->dest_blt_cy = cy; } if (rop != self->dest_blt_rop) @@ -670,29 +862,43 @@ int xrdp_orders_line(struct xrdp_orders* self, int mix_mode, self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->last_order != RDP_ORDER_LINE) + { order_flags |= RDP_ORDER_CHANGE; + } self->last_order = RDP_ORDER_LINE; if (rect != 0) { order_flags |= RDP_ORDER_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) + { order_flags |= RDP_ORDER_LASTBOUNDS; + } } - vals[0] = startx; vals[1] = self->line_startx; - vals[2] = starty; vals[3] = self->line_starty; - vals[4] = endx; vals[5] = self->line_endx; - vals[6] = endy; vals[7] = self->line_endy; + vals[0] = startx; + vals[1] = self->line_startx; + vals[2] = starty; + vals[3] = self->line_starty; + vals[4] = endx; + vals[5] = self->line_endx; + vals[6] = endy; + vals[7] = self->line_endy; if (xrdp_orders_send_delta(self, vals, 8)) + { order_flags |= RDP_ORDER_DELTA; + } out_uint8(self->out_s, order_flags); if (order_flags & RDP_ORDER_CHANGE) - out_uint8(self->out_s, self->last_order) + { + out_uint8(self->out_s, self->last_order); + } present = 0; present_ptr = self->out_s->p; /* hold 2 byte present pointer */ out_uint8s(self->out_s, 2) if ((order_flags & RDP_ORDER_BOUNDS) && !(order_flags & RDP_ORDER_LASTBOUNDS)) + { xrdp_orders_out_bounds(self, rect); + } if (mix_mode != self->line_mix_mode) { present |= 0x0001; @@ -703,36 +909,52 @@ int xrdp_orders_line(struct xrdp_orders* self, int mix_mode, { present |= 0x0002; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, startx - self->line_startx) + { + out_uint8(self->out_s, startx - self->line_startx); + } else - out_uint16_le(self->out_s, startx) + { + out_uint16_le(self->out_s, startx); + } self->line_startx = startx; } if (starty != self->line_starty) { present |= 0x0004; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, starty - self->line_starty) + { + out_uint8(self->out_s, starty - self->line_starty); + } else - out_uint16_le(self->out_s, starty) + { + out_uint16_le(self->out_s, starty); + } self->line_starty = starty; } if (endx != self->line_endx) { present |= 0x0008; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, endx - self->line_endx) + { + out_uint8(self->out_s, endx - self->line_endx); + } else - out_uint16_le(self->out_s, endx) + { + out_uint16_le(self->out_s, endx); + } self->line_endx = endx; } if (endy != self->line_endy) { present |= 0x0010; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, endy - self->line_endy) + { + out_uint8(self->out_s, endy - self->line_endy); + } else - out_uint16_le(self->out_s, endy) + { + out_uint16_le(self->out_s, endy); + } self->line_endy = endy; } if (bg_color != self->line_bg_color) @@ -797,32 +1019,48 @@ int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id, self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->last_order != RDP_ORDER_MEMBLT) + { order_flags |= RDP_ORDER_CHANGE; + } self->last_order = RDP_ORDER_MEMBLT; if (rect != 0) { order_flags |= RDP_ORDER_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) + { order_flags |= RDP_ORDER_LASTBOUNDS; + } } - vals[0] = x; vals[1] = self->mem_blt_x; - vals[2] = y; vals[3] = self->mem_blt_y; - vals[4] = cx; vals[5] = self->mem_blt_cx; - vals[6] = cy; vals[7] = self->mem_blt_cy; - vals[8] = srcx; vals[9] = self->mem_blt_srcx; - vals[10] = srcy; vals[11] = self->mem_blt_srcy; + vals[0] = x; + vals[1] = self->mem_blt_x; + vals[2] = y; + vals[3] = self->mem_blt_y; + vals[4] = cx; + vals[5] = self->mem_blt_cx; + vals[6] = cy; + vals[7] = self->mem_blt_cy; + vals[8] = srcx; + vals[9] = self->mem_blt_srcx; + vals[10] = srcy; + vals[11] = self->mem_blt_srcy; if (xrdp_orders_send_delta(self, vals, 12)) + { order_flags |= RDP_ORDER_DELTA; + } out_uint8(self->out_s, order_flags); if (order_flags & RDP_ORDER_CHANGE) + { out_uint8(self->out_s, self->last_order) + } present = 0; present_ptr = self->out_s->p; /* hold 2 byte present pointer, todo */ out_uint8s(self->out_s, 2) /* this can be smaller, */ /* see RDP_ORDER_SMALL and RDP_ORDER_TINY */ if ((order_flags & RDP_ORDER_BOUNDS) && !(order_flags & RDP_ORDER_LASTBOUNDS)) + { xrdp_orders_out_bounds(self, rect); + } if (cache_id != self->mem_blt_cache_id || color_table != self->mem_blt_color_table) { @@ -836,36 +1074,52 @@ int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id, { present |= 0x0002; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, x - self->mem_blt_x) + { + out_uint8(self->out_s, x - self->mem_blt_x); + } else - out_uint16_le(self->out_s, x) + { + out_uint16_le(self->out_s, x); + } self->mem_blt_x = x; } if (y != self->mem_blt_y) { present |= 0x0004; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, y - self->mem_blt_y) + { + out_uint8(self->out_s, y - self->mem_blt_y); + } else - out_uint16_le(self->out_s, y) + { + out_uint16_le(self->out_s, y); + } self->mem_blt_y = y; } if (cx != self->mem_blt_cx) { present |= 0x0008; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cx - self->mem_blt_cx) + { + out_uint8(self->out_s, cx - self->mem_blt_cx); + } else - out_uint16_le(self->out_s, cx) + { + out_uint16_le(self->out_s, cx); + } self->mem_blt_cx = cx; } if (cy != self->mem_blt_cy) { present |= 0x0010; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, cy - self->mem_blt_cy) + { + out_uint8(self->out_s, cy - self->mem_blt_cy); + } else - out_uint16_le(self->out_s, cy) + { + out_uint16_le(self->out_s, cy); + } self->mem_blt_cy = cy; } if (rop != self->mem_blt_rop) @@ -878,18 +1132,26 @@ int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id, { present |= 0x0040; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, srcx - self->mem_blt_srcx) + { + out_uint8(self->out_s, srcx - self->mem_blt_srcx); + } else - out_uint16_le(self->out_s, srcx) + { + out_uint16_le(self->out_s, srcx); + } self->mem_blt_srcx = srcx; } if (srcy != self->mem_blt_srcy) { present |= 0x0080; if (order_flags & RDP_ORDER_DELTA) - out_uint8(self->out_s, srcy - self->mem_blt_srcy) + { + out_uint8(self->out_s, srcy - self->mem_blt_srcy); + } else - out_uint16_le(self->out_s, srcy) + { + out_uint16_le(self->out_s, srcy); + } self->mem_blt_srcy = srcy; } if (cache_idx != self->mem_blt_cache_idx) @@ -923,25 +1185,32 @@ int xrdp_orders_text(struct xrdp_orders* self, self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->last_order != RDP_ORDER_TEXT2) + { order_flags |= RDP_ORDER_CHANGE; + } self->last_order = RDP_ORDER_TEXT2; if (rect != 0) { order_flags |= RDP_ORDER_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) + { order_flags |= RDP_ORDER_LASTBOUNDS; + } } out_uint8(self->out_s, order_flags); if (order_flags & RDP_ORDER_CHANGE) - out_uint8(self->out_s, self->last_order) + { + out_uint8(self->out_s, self->last_order); + } present = 0; present_ptr = self->out_s->p; /* hold 3 byte present pointer, todo */ out_uint8s(self->out_s, 3) /* this can be smaller, */ /* see RDP_ORDER_SMALL and RDP_ORDER_TINY */ if ((order_flags & RDP_ORDER_BOUNDS) && !(order_flags & RDP_ORDER_LASTBOUNDS)) + { xrdp_orders_out_bounds(self, rect); - + } if (font != self->text_font) { present |= 0x000001; @@ -1095,9 +1364,15 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, int i; int j; int pixel; + int e; + e = bitmap->width % 4; + if (e != 0) + { + e = 4 - e; + } Bpp = (bitmap->bpp + 7) / 8; - bufsize = bitmap->width * bitmap->height * Bpp; + bufsize = (bitmap->width + e) * bitmap->height * Bpp; xrdp_orders_check(self, bufsize + 16); self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; @@ -1108,7 +1383,7 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE); /* type */ out_uint8(self->out_s, cache_id); out_uint8s(self->out_s, 1); /* pad */ - out_uint8(self->out_s, bitmap->width); + out_uint8(self->out_s, bitmap->width + e); out_uint8(self->out_s, bitmap->height); out_uint8(self->out_s, bitmap->bpp); out_uint16_le(self->out_s, bufsize); @@ -1130,9 +1405,95 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, out_uint8(self->out_s, pixel >> 8); } else if (Bpp == 1) + { out_uint8(self->out_s, pixel); + } } + for (j = 0; j < e; j++) + { + out_uint8s(self->out_s, Bpp); + } + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +/* max size width * height * Bpp + 16 */ +int xrdp_orders_send_bitmap(struct xrdp_orders* self, + struct xrdp_bitmap* bitmap, + int cache_id, int cache_idx) +{ + int order_flags; + int len; + int bufsize; + int Bpp; + int i; + int lines_sending; + int e; + struct stream* s; + struct stream* temp_s; + char* p; + + if (bitmap->width > 64) + { + g_printf("error, width > 64\n\r"); + return 1; } + if (bitmap->height > 64) + { + g_printf("error, height > 64\n\r"); + return 1; + } + e = bitmap->width % 4; + if (e != 0) + { + e = 4 - e; + } + make_stream(s); + init_stream(s, 8192); + make_stream(temp_s); + init_stream(temp_s, 8192); + p = s->p; + i = bitmap->height; + lines_sending = xrdp_bitmap_compress(bitmap->data, bitmap->width, + bitmap->height, + s, bitmap->bpp, + 8192, + i - 1, temp_s, e); + if (lines_sending != bitmap->height) + { + free_stream(s); + free_stream(temp_s); + g_printf("error lines_sending != bitmap->height\n\r"); + return 1; + } + bufsize = s->p - p; + //g_printf("bufsize %d\n", bufsize); + Bpp = (bitmap->bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 16); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 9 + 8) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BMPCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint8s(self->out_s, 1); /* pad */ + out_uint8(self->out_s, bitmap->width + e); + out_uint8(self->out_s, bitmap->height); + out_uint8(self->out_s, bitmap->bpp); + out_uint16_le(self->out_s, bufsize + 8); + out_uint16_le(self->out_s, cache_idx); + out_uint8s(self->out_s, 2); /* pad */ + out_uint16_le(self->out_s, bufsize); + out_uint16_le(self->out_s, (bitmap->width + e) * Bpp); /* line size */ + out_uint16_le(self->out_s, (bitmap->width + e) * + Bpp * bitmap->height); /* final size */ + out_uint8a(self->out_s, s->data, bufsize); + free_stream(s); + free_stream(temp_s); return 0; } |