diff options
Diffstat (limited to 'libxrdp/xrdp_orders.c')
| -rw-r--r-- | libxrdp/xrdp_orders.c | 471 |
1 files changed, 445 insertions, 26 deletions
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index 29234173..0e2d90d2 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -20,7 +20,7 @@ #include "libxrdp.h" -#if defined(XRDP_FREERDP1) +#if defined(XRDP_NEUTRINORDP) #include <freerdp/codec/rfx.h> #endif @@ -47,6 +47,12 @@ xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer) init_stream(self->out_s, 16384); self->orders_state.clip_right = 1; /* silly rdp right clip */ self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ + self->jpeg_han = xrdp_jpeg_init(); + self->rfx_min_pixel = rdp_layer->client_info.rfx_min_pixel; + if (self->rfx_min_pixel == 0) + { + self->rfx_min_pixel = 64 * 32; + } return self; } @@ -59,6 +65,7 @@ xrdp_orders_delete(struct xrdp_orders *self) return; } + xrdp_jpeg_deinit(self->jpeg_han); free_stream(self->out_s); g_free(self->orders_state.text_data); g_free(self); @@ -200,6 +207,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size) } else { + xrdp_orders_init(self); return 0; } } @@ -462,7 +470,10 @@ xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy, char *present_ptr; char *order_flags_ptr; - xrdp_orders_check(self, 23); + if (xrdp_orders_check(self, 23) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -630,7 +641,10 @@ xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y, char *present_ptr = (char *)NULL; char *order_flags_ptr = (char *)NULL; - xrdp_orders_check(self, 25); + if (xrdp_orders_check(self, 25) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -819,7 +833,10 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y, char *order_flags_ptr; struct xrdp_brush blank_brush; - xrdp_orders_check(self, 39); + if (xrdp_orders_check(self, 39) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1033,7 +1050,10 @@ xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y, char *present_ptr; char *order_flags_ptr; - xrdp_orders_check(self, 21); + if (xrdp_orders_check(self, 21) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1201,7 +1221,10 @@ xrdp_orders_line(struct xrdp_orders *self, int mix_mode, rop = 0x0d; /* R2_COPYPEN */ } - xrdp_orders_check(self, 32); + if (xrdp_orders_check(self, 32) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1400,7 +1423,10 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id, char *present_ptr = (char *)NULL; char *order_flags_ptr = (char *)NULL; - xrdp_orders_check(self, 30); + if (xrdp_orders_check(self, 30) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1592,6 +1618,335 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id, /*****************************************************************************/ /* returns error */ int APP_CC +xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat, + int srcwidth, int srcrepeat, int* srctransform, + int mskflags, int mskidx, int mskformat, + int mskwidth, int mskrepeat, int op, + int srcx, int srcy, int mskx, int msky, + int dstx, int dsty, int width, int height, + int dstformat, + struct xrdp_rect* rect) +{ + int order_flags; + int vals[20]; + int present; + char* present_ptr; + char* order_flags_ptr; + + if (xrdp_orders_check(self, 80) != 0) + { + return 1; + } + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + if (self->orders_state.last_order != RDP_ORDER_COMPOSITE) + { + order_flags |= RDP_ORDER_CHANGE; + } + self->orders_state.last_order = RDP_ORDER_COMPOSITE; + if (rect != 0) + { + /* if clip is present, still check if its needed */ + if (dstx < rect->left || dsty < rect->top || + dstx + width > rect->right || dsty + height > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + if (xrdp_orders_last_bounds(self, rect)) + { + + order_flags |= RDP_ORDER_LASTBOUNDS; + + } + } + } + vals[0] = srcx; + vals[1] = self->orders_state.com_blt_srcx; + vals[2] = srcy; + vals[3] = self->orders_state.com_blt_srcy; + vals[4] = mskx; + vals[5] = self->orders_state.com_blt_mskx; + vals[6] = msky; + vals[7] = self->orders_state.com_blt_msky; + vals[8] = dstx; + vals[9] = self->orders_state.com_blt_dstx; + vals[10] = dsty; + vals[11] = self->orders_state.com_blt_dsty; + vals[12] = width; + vals[13] = self->orders_state.com_blt_width; + vals[14] = height; + vals[15] = self->orders_state.com_blt_height; + vals[16] = srcwidth; + vals[17] = self->orders_state.com_blt_srcwidth; + vals[18] = mskwidth; + vals[19] = self->orders_state.com_blt_mskwidth; + if (xrdp_orders_send_delta(self, vals, 20)) + { + order_flags |= RDP_ORDER_DELTA; + } + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + if (order_flags & RDP_ORDER_CHANGE) + { + out_uint8(self->out_s, self->orders_state.last_order); + } + present = 0; + /* present, set later, 3 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 3); + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) + { + xrdp_orders_out_bounds(self, rect); + } + + if (srcidx != self->orders_state.com_blt_srcidx) + { + present |= 0x000001; + out_uint16_le(self->out_s, srcidx); + self->orders_state.com_blt_srcidx = srcidx; + } + + if (srcformat != self->orders_state.com_blt_srcformat) + { + present |= 0x000002; + out_uint32_le(self->out_s, srcformat); + self->orders_state.com_blt_srcformat = srcformat; + } + + if (srcwidth != self->orders_state.com_blt_srcwidth) + { + present |= 0x000004; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcwidth - self->orders_state.com_blt_srcwidth); + } + else + { + out_uint16_le(self->out_s, srcwidth); + } + self->orders_state.com_blt_srcwidth = srcwidth; + } + + if (srcrepeat != self->orders_state.com_blt_srcrepeat) + { + present |= 0x000008; + out_uint8(self->out_s, srcrepeat); + self->orders_state.com_blt_srcrepeat = srcrepeat; + } + + if (srctransform != 0) + { + if (srctransform[0] != self->orders_state.com_blt_srctransform[0]) + { + present |= 0x000010; + out_uint32_le(self->out_s, srctransform[0]); + self->orders_state.com_blt_srctransform[0] = srctransform[0]; + } + if (g_memcmp(&(srctransform[1]), + &(self->orders_state.com_blt_srctransform[1]), + 36) != 0) + { + present |= 0x000020; + out_uint32_le(self->out_s, srctransform[1]); + out_uint32_le(self->out_s, srctransform[2]); + out_uint32_le(self->out_s, srctransform[3]); + out_uint32_le(self->out_s, srctransform[4]); + out_uint32_le(self->out_s, srctransform[5]); + out_uint32_le(self->out_s, srctransform[6]); + out_uint32_le(self->out_s, srctransform[7]); + out_uint32_le(self->out_s, srctransform[8]); + out_uint32_le(self->out_s, srctransform[9]); + } + } + else + { + if (self->orders_state.com_blt_srctransform[0] != 0) + { + present |= 0x000010; + out_uint32_le(self->out_s, 0); + self->orders_state.com_blt_srctransform[0] = 0; + } + } + + if (mskflags != self->orders_state.com_blt_mskflags) + { + present |= 0x000040; + out_uint8(self->out_s, mskflags); + self->orders_state.com_blt_mskflags = mskflags; + } + + if (mskidx != self->orders_state.com_blt_mskidx) + { + present |= 0x000080; + out_uint16_le(self->out_s, mskidx); + self->orders_state.com_blt_mskidx = mskidx; + } + + if (mskformat != self->orders_state.com_blt_mskformat) + { + present |= 0x000100; + out_uint32_le(self->out_s, mskformat); + self->orders_state.com_blt_mskformat = mskformat; + } + + if (mskwidth != self->orders_state.com_blt_mskwidth) + { + present |= 0x000200; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, mskwidth - self->orders_state.com_blt_mskwidth); + } + else + { + out_uint16_le(self->out_s, mskwidth); + } + self->orders_state.com_blt_mskwidth = mskwidth; + } + + if (mskrepeat != self->orders_state.com_blt_mskrepeat) + { + present |= 0x000400; + out_uint8(self->out_s, mskrepeat); + self->orders_state.com_blt_mskrepeat = mskrepeat; + } + + if (op != self->orders_state.com_blt_op) + { + present |= 0x000800; + out_uint8(self->out_s, op); + self->orders_state.com_blt_op = op; + } + + if (srcx != self->orders_state.com_blt_srcx) + { + present |= 0x001000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcx - self->orders_state.com_blt_srcx); + } + else + { + out_uint16_le(self->out_s, srcx); + } + self->orders_state.com_blt_srcx = srcx; + } + + if (srcy != self->orders_state.com_blt_srcy) + { + present |= 0x002000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcy - self->orders_state.com_blt_srcy); + } + else + { + out_uint16_le(self->out_s, srcy); + } + self->orders_state.com_blt_srcy = srcy; + } + + if (mskx != self->orders_state.com_blt_mskx) + { + present |= 0x004000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, mskx - self->orders_state.com_blt_mskx); + } + else + { + out_uint16_le(self->out_s, mskx); + } + self->orders_state.com_blt_mskx = mskx; + } + + if (msky != self->orders_state.com_blt_msky) + { + present |= 0x008000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, msky - self->orders_state.com_blt_msky); + } + else + { + out_uint16_le(self->out_s, msky); + } + self->orders_state.com_blt_msky = msky; + } + + if (dstx != self->orders_state.com_blt_dstx) + { + present |= 0x010000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, dstx - self->orders_state.com_blt_dstx); + } + else + { + out_uint16_le(self->out_s, dstx); + } + self->orders_state.com_blt_dstx = dstx; + } + + if (dsty != self->orders_state.com_blt_dsty) + { + present |= 0x020000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, dsty - self->orders_state.com_blt_dsty); + } + else + { + out_uint16_le(self->out_s, dsty); + } + self->orders_state.com_blt_dsty = dsty; + } + + if (width != self->orders_state.com_blt_width) + { + present |= 0x040000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, width - self->orders_state.com_blt_width); + } + else + { + out_uint16_le(self->out_s, width); + } + self->orders_state.com_blt_width = width; + } + + if (height != self->orders_state.com_blt_height) + { + present |= 0x080000; + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, height - self->orders_state.com_blt_height); + } + else + { + out_uint16_le(self->out_s, height); + } + self->orders_state.com_blt_height = height; + } + + if (dstformat != self->orders_state.com_blt_dstformat) + { + present |= 0x100000; + out_uint32_le(self->out_s, dstformat); + self->orders_state.com_blt_dstformat = dstformat; + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + + present_ptr, present, 3); + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC xrdp_orders_text(struct xrdp_orders *self, int font, int flags, int mixmode, int fg_color, int bg_color, @@ -1607,8 +1962,10 @@ xrdp_orders_text(struct xrdp_orders *self, char *present_ptr = (char *)NULL; char *order_flags_ptr = (char *)NULL; - //xrdp_orders_check(self, 100); - xrdp_orders_check(self, 44+data_len); + if (xrdp_orders_check(self, 44 + data_len) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1794,7 +2151,10 @@ xrdp_orders_send_palette(struct xrdp_orders *self, int *palette, int len; int i; - xrdp_orders_check(self, 2000); + if (xrdp_orders_check(self, 2000) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -1854,7 +2214,10 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self, Bpp = (bpp + 7) / 8; bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 16); + if (xrdp_orders_check(self, bufsize + 16) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -1961,7 +2324,10 @@ height(%d)", lines_sending, height); bufsize = (int)(s->p - p); Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 16); + if (xrdp_orders_check(self, bufsize + 16) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2015,15 +2381,28 @@ xrdp_orders_send_font(struct xrdp_orders *self, int order_flags = 0; int datasize = 0; int len = 0; + int flags; - datasize = FONT_DATASIZE(font_char); - xrdp_orders_check(self, datasize + 18); + if (font_char->bpp == 8) /* alpha font */ + { + datasize = ((font_char->width + 3) & ~3) * font_char->height; + flags = 8 | 0x4000; + } + else + { + datasize = FONT_DATASIZE(font_char); + flags = 8; + } + if (xrdp_orders_check(self, datasize + 18) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); len = (datasize + 12) - 7; /* length after type minus 7 */ out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 8); /* flags */ + out_uint16_le(self->out_s, flags); out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ out_uint8(self->out_s, font_index); out_uint8(self->out_s, 1); /* num of chars */ @@ -2074,7 +2453,10 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self, Bpp = (bpp + 7) / 8; bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 14); + if (xrdp_orders_check(self, bufsize + 14) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2091,6 +2473,25 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self, i = cache_idx & 0xff; out_uint8(self->out_s, i); + if (1 && Bpp == 3) + { + for (i = height - 1; i >= 0; i--) + { + for (j = 0; j < width; j++) + { + pixel = GETPIXEL32(data, j, i, width); + out_uint8(self->out_s, pixel); + out_uint8(self->out_s, pixel >> 8); + out_uint8(self->out_s, pixel >> 16); + } + for (j = 0; j < e; j++) + { + out_uint8s(self->out_s, Bpp); + } + } + } + else + { for (i = height - 1; i >= 0; i--) { for (j = 0; j < width; j++) @@ -2120,6 +2521,7 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self, out_uint8s(self->out_s, Bpp); } } + } return 0; } @@ -2182,7 +2584,10 @@ height(%d)", lines_sending, height); bufsize = (int)(s->p - p); Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 14); + if (xrdp_orders_check(self, bufsize + 14) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2228,7 +2633,7 @@ xrdp_orders_send_as_jpeg(struct xrdp_orders *self, return 1; } -#if defined(XRDP_FREERDP1) +#if defined(XRDP_NEUTRINORDP) /*****************************************************************************/ /* secondary drawing order (bitmap v3) using remotefx compression */ static int APP_CC @@ -2246,7 +2651,9 @@ xrdp_orders_send_as_rfx(struct xrdp_orders *self, return 0; } - if (width * height < 64) + LLOGLN(10, ("width %d height %d rfx_min_pixel %d", width, height, + self->rfx_min_pixel)); + if (width * height < self->rfx_min_pixel) { return 0; } @@ -2267,7 +2674,10 @@ xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx, int i; Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 30); + if (xrdp_orders_check(self, bufsize + 30) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2306,7 +2716,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self, struct stream *xr_s; /* xrdp stream */ struct stream *temp_s; /* xrdp stream */ struct xrdp_client_info *ci; -#if defined(XRDP_FREERDP1) +#if defined(XRDP_NEUTRINORDP) STREAM *fr_s; /* FreeRDP stream */ RFX_CONTEXT *context; RFX_RECT rect; @@ -2321,7 +2731,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self, if (ci->v3_codec_id == ci->rfx_codec_id) { -#if defined(XRDP_FREERDP1) +#if defined(XRDP_NEUTRINORDP) if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints)) { @@ -2374,7 +2784,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self, make_stream(temp_s); init_stream(temp_s, 16384); quality = ci->jpeg_prop[0]; - xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384, + xrdp_jpeg_compress(self->jpeg_han, data, width, height, xr_s, bpp, 16384, height - 1, temp_s, e, quality); s_mark_end(xr_s); bufsize = (int)(xr_s->end - xr_s->data); @@ -2406,7 +2816,10 @@ xrdp_orders_send_brush(struct xrdp_orders *self, int width, int height, int order_flags = 0; int len = 0; - xrdp_orders_check(self, size + 12); + if (xrdp_orders_check(self, size + 12) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2448,7 +2861,10 @@ xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id, bytes += num_del_list * 2; } - xrdp_orders_check(self, bytes); + if (xrdp_orders_check(self, bytes) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ @@ -2489,7 +2905,10 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id) int order_flags; int cache_id; - xrdp_orders_check(self, 3); + if (xrdp_orders_check(self, 3) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */ |
