summaryrefslogtreecommitdiffstats
path: root/libxrdp/xrdp_orders.c
diff options
context:
space:
mode:
Diffstat (limited to 'libxrdp/xrdp_orders.c')
-rw-r--r--libxrdp/xrdp_orders.c471
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 */