Hand-apply patch (compositing) from Authentic8: 5d5e470 81c9c29 b0c2c10 27d8a01 a96a217 e512090 a9a6762 9c02bfa bd26fcc c0d29d9 676dd35 3b26737

ulab-next
Jim Grandy 12 years ago
parent eef1ca3937
commit c42ae35252

@ -416,6 +416,7 @@
#define RDP_ORDER_TRIBLT 14
#define RDP_ORDER_POLYLINE 22
#define RDP_ORDER_TEXT2 27
#define RDP_ORDER_COMPOSITE 37 /* 0x25 */
#define RDP_ORDER_RAW_BMPCACHE 0
#define RDP_ORDER_COLCACHE 1

@ -628,6 +628,25 @@ libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id,
srcx, srcy, cache_idx, rect);
}
/******************************************************************************/
int DEFAULT_CC
libxrdp_orders_composite_blt(struct xrdp_session* session, 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)
{
return xrdp_orders_composite_blt((struct xrdp_orders*)session->orders,
srcidx, srcformat, srcwidth, srcrepeat,
srctransform, mskflags,
mskidx, mskformat, mskwidth, mskrepeat,
op, srcx, srcy, mskx, msky, dstx, dsty,
width, height, dstformat, rect);
}
/******************************************************************************/
int EXPORT_CC
libxrdp_orders_text(struct xrdp_session *session,

@ -197,6 +197,28 @@ struct xrdp_orders_state
int text_y;
int text_len;
char* text_data;
int com_blt_srcidx; /* RDP_ORDER_COMPOSITE */ /* 2 */
int com_blt_srcformat; /* 2 */
int com_blt_srcwidth; /* 2 */
int com_blt_srcrepeat; /* 1 */
int com_blt_srctransform[10]; /* 40 */
int com_blt_mskflags; /* 1 */
int com_blt_mskidx; /* 2 */
int com_blt_mskformat; /* 2 */
int com_blt_mskwidth; /* 2 */
int com_blt_mskrepeat; /* 1 */
int com_blt_op; /* 1 */
int com_blt_srcx; /* 2 */
int com_blt_srcy; /* 2 */
int com_blt_mskx; /* 2 */
int com_blt_msky; /* 2 */
int com_blt_dstx; /* 2 */
int com_blt_dsty; /* 2 */
int com_blt_width; /* 2 */
int com_blt_height; /* 2 */
int com_blt_dstformat; /* 2 */
};
/* orders */
@ -379,6 +401,15 @@ xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect);
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 APP_CC
xrdp_orders_text(struct xrdp_orders* self,
int font, int flags, int mixmode,
int fg_color, int bg_color,

@ -130,6 +130,16 @@ libxrdp_orders_mem_blt(struct xrdp_session* session, int cache_id,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect);
int DEFAULT_CC
libxrdp_orders_composite_blt(struct xrdp_session* session, 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 DEFAULT_CC
libxrdp_orders_text(struct xrdp_session* session,
int font, int flags, int mixmode,
int fg_color, int bg_color,

@ -1594,6 +1594,332 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
return 0;
}
/*****************************************************************************/
/* 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;
xrdp_orders_check(self, 80);
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

@ -13,7 +13,7 @@ rdpPolylines.o rdpPolySegment.o rdpFillSpans.o rdpSetSpans.o \
rdpCopyPlane.o rdpPolyPoint.o rdpPolyArc.o rdpFillPolygon.o \
rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o \
rdpImageText8.o rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o \
rdpPushPixels.o rdpxv.o rdpglyph.o \
rdpPushPixels.o rdpxv.o rdpglyph.o rdpComposite.o \
miinitext.o \
fbcmap_mi.o

@ -282,13 +282,19 @@ struct rdp_draw_item
union urdp_draw_item u;
};
#define XRDP_USE_COUNT_THRESHOLD 1
struct _rdpPixmapRec
{
int status;
int rdpindex;
int con_number;
int is_dirty;
int pad0;
int is_alpha_dirty_not;
/* number of times used in a remote operation
if this gets above XRDP_USE_COUNT_THRESHOLD
then we force remote the pixmap */
int use_count;
int kind_width;
struct rdp_draw_item* draw_item_head;
struct rdp_draw_item* draw_item_tail;
@ -446,6 +452,14 @@ rdpDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor);
void
rdpRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
Bool displayed);
/* rdpglyph.c */
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int nlists, GlyphListPtr lists, GlyphPtr* glyphs);
/* rdpComposite.c */
int
rdpCreatePicture(PicturePtr pPicture);
void
@ -543,6 +557,8 @@ rdpup_set_cursor_ex(short x, short y, char *cur_data, char *cur_mask, int bpp);
int
rdpup_create_os_surface(int rdpindexd, int width, int height);
int
rdpup_create_os_surface_bpp(int rdpindexd, int width, int height, int bpp);
int
rdpup_switch_os_surface(int rdpindex);
int
rdpup_delete_os_surface(int rdpindex);
@ -559,6 +575,8 @@ rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv);
int
rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv);
int
rdpup_check_alpha_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv);
int
rdpup_check_dirty_screen(rdpPixmapRec* pDirtyPriv);
int
rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
@ -573,6 +591,13 @@ rdpup_draw_text(int font, int flags, int mixmode,
short box_left, short box_top,
short box_right, short box_bottom, short x, short y,
char* data, int data_bytes);
int
rdpup_composite(short srcidx, int srcformat, short srcwidth, CARD8 srcrepeat,
PictTransform* srctransform, CARD8 mskflags,
short mskidx, int mskformat, short mskwidth, CARD8 mskrepeat,
CARD8 op, short srcx, short srcy, short mskx, short msky,
short dstx, short dsty, short width, short height,
int dstformat);
void
rdpScheduleDeferredUpdate(void);
@ -670,6 +695,13 @@ struct stream
out_uint8p((s), (v), (n)); \
}
/******************************************************************************/
#define out_uint8s(s, n) do \
{ \
memset((s)->p, 0, (n)); \
(s)->p += (n); \
} while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define out_uint32_le(s, v) \

@ -70,8 +70,6 @@ extern int g_do_glyph_cache; /* in rdpmain.c */
ColormapPtr g_rdpInstalledColormap;
static int g_doing_font = 0;
GCFuncs g_rdpGCFuncs =
{
rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip,
@ -409,6 +407,8 @@ rdpCloseScreen(int i, ScreenPtr pScreen)
int
draw_item_add(rdpPixmapRec *priv, struct rdp_draw_item *di)
{
priv->is_alpha_dirty_not = 0;
if (priv->draw_item_tail == 0)
{
priv->draw_item_tail = di;
@ -667,6 +667,17 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
while (di != 0)
{
#if 0
if ((di_prev->type == RDI_IMGLL || di_prev->type == RDI_IMGLY) &&
(di->type == RDI_IMGLL || di->type == RDI_IMGLY))
{
LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL and RDI_IMGLY"));
di_prev->type = RDI_IMGLY;
RegionUnion(di_prev->reg, di_prev->reg, di->reg);
draw_item_remove(priv, di);
di = di_prev->next;
}
#else
if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL))
{
LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL"));
@ -674,6 +685,7 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
draw_item_remove(priv, di);
di = di_prev->next;
}
#endif
else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY))
{
LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY"));
@ -756,7 +768,7 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
remove_empties(priv);
#endif
#if 1
#if 0
if (priv->draw_item_tail != 0)
{
if (priv->draw_item_tail->prev != 0)
@ -796,6 +808,38 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
remove_empties(priv);
#endif
#if 0
/* subtract regions */
if (priv->draw_item_tail != 0)
{
if (priv->draw_item_tail->prev != 0)
{
di = priv->draw_item_tail;
while (di->prev != 0)
{
/* skip subtract flag
* draw items like line can't be used to clear(subtract) previous
* draw items since they are not opaque
* eg they can not be the 'S' in 'D = M - S'
* the region for line draw items is the clip region */
if ((di->flags & 1) == 0)
{
di_prev = di->prev;
while (di_prev != 0)
{
/* D = M - S */
RegionSubtract(di_prev->reg, di_prev->reg, di->reg);
di_prev = di_prev->prev;
}
}
di = di->prev;
}
}
}
remove_empties(priv);
#endif
return 0;
}
@ -942,12 +986,12 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
width, org_width, depth, g_rdpScreen.depth));
pScreen->CreatePixmap = g_rdpScreen.CreatePixmap;
rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
pScreen->CreatePixmap = rdpCreatePixmap;
priv = GETPIXPRIV(rv);
priv->rdpindex = -1;
priv->con_number = g_con_number;
priv->kind_width = width;
pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0);
pScreen->CreatePixmap = rdpCreatePixmap;
return rv;
}
@ -982,6 +1026,64 @@ rdpDestroyPixmap(PixmapPtr pPixmap)
return rv;
}
/*****************************************************************************/
int
xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv)
{
RegionRec reg1;
BoxRec box;
int width;
int height;
struct image_data id;
if (priv->status == 0)
{
width = pix->drawable.width;
height = pix->drawable.height;
if ((pix->usage_hint == 0) &&
(pix->drawable.depth >= g_rdpScreen.depth) &&
(width > 0) && (height > 0) &&
(priv->use_count > XRDP_USE_COUNT_THRESHOLD))
{
width = (width + 3) & ~3;
priv->rdpindex = rdpup_add_os_bitmap(pix, priv);
if (priv->rdpindex >= 0)
{
priv->status = 1;
rdpup_create_os_surface(priv->rdpindex, width, height);
box.x1 = 0;
box.y1 = 0;
box.x2 = width;
box.y2 = height;
if (g_do_dirty_os)
{
draw_item_remove_all(priv);
RegionInit(&reg1, &box, 0);
draw_item_add_img_region(priv, &reg1, GXcopy, RDI_IMGLY, 16);
RegionUninit(&reg1);
priv->is_dirty = 1;
}
else
{
rdpup_get_pixmap_image_rect(pix, &id);
rdpup_switch_os_surface(priv->rdpindex);
rdpup_begin_update();
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
box.y2 - box.y1);
rdpup_end_update();
rdpup_switch_os_surface(-1);
}
priv->use_count++;
return 1;
}
}
priv->use_count++;
return 0;
}
priv->use_count++;
return 1;
}
/*****************************************************************************/
int
xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv)
@ -1500,284 +1602,3 @@ rdpSaveScreen(ScreenPtr pScreen, int on)
return 1;
}
/******************************************************************************/
int
rdpCreatePicture(PicturePtr pPicture)
{
PictureScreenPtr ps;
int rv;
LLOGLN(10, ("rdpCreatePicture:"));
ps = GetPictureScreen(g_pScreen);
ps->CreatePicture = g_rdpScreen.CreatePicture;
rv = ps->CreatePicture(pPicture);
ps->CreatePicture = rdpCreatePicture;
return rv;
}
/******************************************************************************/
void
rdpDestroyPicture(PicturePtr pPicture)
{
PictureScreenPtr ps;
LLOGLN(10, ("rdpDestroyPicture:"));
ps = GetPictureScreen(g_pScreen);
ps->DestroyPicture = g_rdpScreen.DestroyPicture;
ps->DestroyPicture(pPicture);
ps->DestroyPicture = rdpDestroyPicture;
}
/******************************************************************************/
/* it looks like all the antialias draws go through here
op is one of the following
#define PictOpMinimum 0
#define PictOpClear 0
#define PictOpSrc 1
#define PictOpDst 2
#define PictOpOver 3
#define PictOpOverReverse 4
#define PictOpIn 5
#define PictOpInReverse 6
#define PictOpOut 7
#define PictOpOutReverse 8
#define PictOpAtop 9
#define PictOpAtopReverse 10
#define PictOpXor 11
#define PictOpAdd 12
#define PictOpSaturate 13
#define PictOpMaximum 13
see for porter duff
http://www.svgopen.org/2005/papers/abstractsvgopen/
*/
void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height)
{
BoxRec box;
PictureScreenPtr ps;
RegionRec reg1;
RegionRec reg2;
DrawablePtr p;
int dirty_type;
int j;
int num_clips;
int post_process;
int reset_surface;
int got_id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec *pDstPriv;
rdpPixmapRec *pDirtyPriv;
struct image_data id;
LLOGLN(10, ("rdpComposite:"));
ps = GetPictureScreen(g_pScreen);
ps->Composite = g_rdpScreen.Composite;
ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
ps->Composite = rdpComposite;
if (g_doing_font == 2)
{
return;
}
LLOGLN(10, ("rdpComposite: op %d %p %p %p w %d h %d", op, pSrc, pMask, pDst, width, height));
p = pDst->pDrawable;
dirty_type = 0;
pDirtyPriv = 0;
post_process = 0;
reset_surface = 0;
got_id = 0;
if (p->type == DRAWABLE_PIXMAP)
{
pDstPixmap = (PixmapPtr)p;
pDstPriv = GETPIXPRIV(pDstPixmap);
if (xrdp_is_os(pDstPixmap, pDstPriv))
{
post_process = 1;
if (g_do_dirty_os)
{
LLOGLN(10, ("rdpComposite: gettig dirty"));
pDstPriv->is_dirty = 1;
dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
pDirtyPriv = pDstPriv;
}
else
{
rdpup_switch_os_surface(pDstPriv->rdpindex);
reset_surface = 1;
rdpup_get_pixmap_image_rect(pDstPixmap, &id);
got_id = 1;
LLOGLN(10, ("rdpComposite: offscreen"));
}
}
}
else
{
if (p->type == DRAWABLE_WINDOW)
{
pDstWnd = (WindowPtr)p;
if (pDstWnd->viewable)
{
post_process = 1;
if (g_do_dirty_ons)
{
LLOGLN(0, ("rdpComposite: gettig dirty"));
g_screenPriv.is_dirty = 1;
pDirtyPriv = &g_screenPriv;
dirty_type = RDI_IMGLL;
}
else
{
rdpup_get_screen_image_rect(&id);
got_id = 1;
LLOGLN(10, ("rdpComposite: screen"));
}
}
}
}
if (!post_process)
{
return;
}
if (pDst->pCompositeClip != 0)
{
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
RegionInit(&reg1, &box, 0);
RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, pDst->pCompositeClip);
RegionIntersect(&reg1, &reg1, &reg2);
if (dirty_type != 0)
{
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COMPOSITE);
}
else if (got_id)
{
num_clips = REGION_NUM_RECTS(&reg1);
if (num_clips > 0)
{
rdpup_begin_update();
for (j = num_clips - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg1)[j];
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_end_update();
}
}
RegionUninit(&reg1);
RegionUninit(&reg2);
}
else
{
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
if (dirty_type != 0)
{
RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COMPOSITE);
RegionUninit(&reg1);
}
else if (got_id)
{
rdpup_begin_update();
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
rdpup_end_update();
}
}
if (reset_surface)
{
rdpup_switch_os_surface(-1);
}
}
/******************************************************************************/
/* make sure no glyph is too big */
/* returns boolean */
static int
rdpGlyphCheck(int nlist, GlyphListPtr list, GlyphPtr* glyphs)
{
int n;
GlyphPtr glyph;
while (nlist--)
{
n = list->len;
list++;
while (n--)
{
glyph = *glyphs++;
if ((glyph->info.width * glyph->info.height) > 8192)
{
LLOGLN(10, ("rdpGlyphCheck: too big"));
return 0;
}
}
}
return 1;
}
/******************************************************************************/
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
GlyphPtr *glyphs)
{
PictureScreenPtr ps;
LLOGLN(10, ("rdpGlyphs: op %d xSrc %d ySrc %d maskFormat %p", op, xSrc, ySrc, maskFormat));
if (g_do_glyph_cache && rdpGlyphCheck(nlists, lists, glyphs))
{
g_doing_font = 2;
ps = GetPictureScreen(g_pScreen);
ps->Glyphs = g_rdpScreen.Glyphs;
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
nlists, lists, glyphs);
ps->Glyphs = rdpGlyphs;
rdpGlypht(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs);
}
else
{
g_doing_font = 1;
rdpup_set_hints(1, 1);
ps = GetPictureScreen(g_pScreen);
ps->Glyphs = g_rdpScreen.Glyphs;
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
nlists, lists, glyphs);
ps->Glyphs = rdpGlyphs;
rdpup_set_hints(0, 1);
}
g_doing_font = 0;
LLOGLN(10, ("rdpGlyphs: out"));
}

@ -544,6 +544,7 @@ rdpGlyphu(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
rdpup_check_dirty(pDstPixmap, pDstPriv);
post_process = 1;
if (g_do_dirty_os)
{

@ -48,8 +48,9 @@ int g_can_do_pix_to_pix = 0;
int g_do_dirty_os = 1; /* delay remoting off screen bitmaps */
int g_do_dirty_ons = 0; /* delay remoting screen */
int g_do_glyph_cache = 0;
int g_do_glyph_cache = 0; /* rdpup.c may set this */
int g_do_alpha_glyphs = 1;
int g_do_composite = 0; /* rdpup.c may set this */
Bool g_wrapWindow = 1;
Bool g_wrapPixmap = 1;
@ -61,6 +62,7 @@ int g_use_rail = 0;
int g_con_number = 0; /* increments for each connection */
WindowPtr g_invalidate_window = 0;
int g_doing_font = 0;
/* if true, use a unix domain socket instead of a tcp socket */
int g_use_uds = 0;

@ -57,6 +57,7 @@ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
extern int g_do_glyph_cache; /* from rdpmain.c */
extern int g_can_do_pix_to_pix; /* from rdpmain.c */
extern int g_use_rail; /* from rdpmain.c */
extern int g_do_composite; /* from rdpmain.c */
/* true is to use unix domain socket */
extern int g_use_uds; /* in rdpmain.c */
@ -159,6 +160,7 @@ rdpup_disconnect(void)
g_os_bitmaps = 0;
g_use_rail = 0;
g_do_glyph_cache = 0;
g_do_composite = 0;
return 0;
}
@ -347,6 +349,9 @@ rdpup_send_msg(struct stream *s)
static int
rdpup_send_pending(void)
{
int rv;
rv = 0;
if (g_connected && g_begin)
{
LLOGLN(10, ("end %d", g_count));
@ -354,12 +359,16 @@ rdpup_send_pending(void)
out_uint16_le(g_out_s, 4);
g_count++;
s_mark_end(g_out_s);
rdpup_send_msg(g_out_s);
if (rdpup_send_msg(g_out_s) != 0)
{
LLOGLN(0, ("rdpup_send_pending: rdpup_send_msg failed"));
rv = 1;
}
}
g_count = 0;
g_begin = 0;
return 0;
return rv;
}
/******************************************************************************/
@ -781,10 +790,19 @@ rdpup_process_msg(struct stream *s)
{
g_do_glyph_cache = 1;
}
if (g_rdpScreen.client_info.order_flags_ex & 0x100)
{
g_do_composite = 1;
}
if (g_do_glyph_cache)
{
LLOGLN(0, (" using glyph cache"));
}
if (g_do_composite)
{
LLOGLN(0, (" using client composite"));
}
LLOGLN(10, ("order_flags_ex 0x%x", g_rdpScreen.client_info.order_flags_ex));
if (g_rdpScreen.client_info.offscreen_cache_entries == 2000)
{
LLOGLN(0, (" client can do offscreen to offscreen blits"));
@ -1040,6 +1058,9 @@ rdpup_end_update(void)
int
rdpup_pre_check(int in_size)
{
int rv;
rv = 0;
if (!g_begin)
{
rdpup_begin_update();
@ -1048,13 +1069,17 @@ rdpup_pre_check(int in_size)
if ((g_out_s->p - g_out_s->data) > (g_out_s->size - (in_size + 20)))
{
s_mark_end(g_out_s);
rdpup_send_msg(g_out_s);
if (rdpup_send_msg(g_out_s) != 0)
{
LLOGLN(0, ("rdpup_pre_check: rdpup_send_msg failed"));
rv = 1;
}
g_count = 0;
init_stream(g_out_s, 0);
s_push_layer(g_out_s, iso_hdr, 8);
}
return 0;
return rv;
}
/******************************************************************************/
@ -1277,6 +1302,25 @@ convert_pixels(void *src, void *dst, int num_pixels)
return 0;
}
/******************************************************************************/
int
alpha_pixels(void* src, void* dst, int num_pixels)
{
unsigned int* src32;
unsigned char* dst8;
int index;
src32 = (unsigned int*)src;
dst8 = (unsigned char*)dst;
for (index = 0; index < num_pixels; index++)
{
*dst8 = (*src32) >> 24;
dst8++;
src32++;
}
return 0;
}
/******************************************************************************/
int
rdpup_set_fgcolor(int fgcolor)
@ -1448,6 +1492,26 @@ rdpup_create_os_surface(int rdpindex, int width, int height)
return 0;
}
/******************************************************************************/
int
rdpup_create_os_surface_bpp(int rdpindex, int width, int height, int bpp)
{
LLOGLN(10, ("rdpup_create_os_surface_bpp:"));
if (g_connected)
{
LLOGLN(10, (" width %d height %d bpp %d", width, height, bpp));
rdpup_pre_check(13);
out_uint16_le(g_out_s, 31);
out_uint16_le(g_out_s, 13);
g_count++;
out_uint32_le(g_out_s, rdpindex);
out_uint16_le(g_out_s, width);
out_uint16_le(g_out_s, height);
out_uint8(g_out_s, bpp);
}
return 0;
}
/******************************************************************************/
int
rdpup_switch_os_surface(int rdpindex)
@ -1653,7 +1717,7 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h)
LLOGLN(10, (" rdpup_send_area"));
ly = y;
while (ly < y + h)
while ((ly < y + h) && g_connected)
{
lx = x;
@ -1704,6 +1768,103 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h)
}
}
/******************************************************************************/
/* split the bitmap up into 64 x 64 pixel areas */
void
rdpup_send_alpha_area(struct image_data* id, int x, int y, int w, int h)
{
char* s;
int i;
int lx;
int ly;
int lh;
int lw;
int size;
struct image_data lid;
LLOGLN(10, ("rdpup_send_alpha_area: id %p x %d y %d w %d h %d",
id, x, y, w, h));
if (id == 0)
{
rdpup_get_screen_image_rect(&lid);
id = &lid;
}
if (x >= id->width)
{
return;
}
if (y >= id->height)
{
return;
}
if (x < 0)
{
w += x;
x = 0;
}
if (y < 0)
{
h += y;
y = 0;
}
if (w <= 0)
{
return;
}
if (h <= 0)
{
return;
}
if (x + w > id->width)
{
w = id->width - x;
}
if (y + h > id->height)
{
h = id->height - y;
}
LLOGLN(10, ("%d", w * h));
if (g_connected && g_begin)
{
LLOGLN(10, (" rdpup_send_area"));
ly = y;
while ((ly < y + h) && g_connected)
{
lx = x;
while ((lx < x + w) && g_connected)
{
lw = MIN(64, (x + w) - lx);
lh = MIN(64, (y + h) - ly);
size = lw * lh + 25;
rdpup_pre_check(size);
out_uint16_le(g_out_s, 32); /* server_paint_rect_bpp */
out_uint16_le(g_out_s, size);
g_count++;
out_uint16_le(g_out_s, lx);
out_uint16_le(g_out_s, ly);
out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh);
out_uint32_le(g_out_s, lw * lh);
for (i = 0; i < lh; i++)
{
s = (id->pixels +
((ly + i) * id->lineBytes) + (lx * g_Bpp));
alpha_pixels(s, g_out_s->p, lw);
g_out_s->p += lw;
}
out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh);
out_uint16_le(g_out_s, 0);
out_uint16_le(g_out_s, 0);
out_uint8(g_out_s, 8);
lx += 64;
}
ly += 64;
}
}
}
/******************************************************************************/
void
rdpup_paint_rect_os(int x, int y, int cx, int cy,
@ -2173,6 +2334,35 @@ rdpup_check_dirty_screen(rdpPixmapRec *pDirtyPriv)
return 0;
}
/******************************************************************************/
int
rdpup_check_alpha_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv)
{
struct image_data id;
LLOGLN(10, ("rdpup_check_alpha_dirty: width %d height %d",
pDirtyPixmap->drawable.width, pDirtyPixmap->drawable.height));
if (pDirtyPriv == 0)
{
return 0;
}
LLOGLN(10, ("rdpup_check_alpha_dirty: is_alpha_dirty_not %d",
pDirtyPriv->is_alpha_dirty_not));
if (pDirtyPriv->is_alpha_dirty_not)
{
return 0;
}
pDirtyPriv->is_alpha_dirty_not = 1;
rdpup_switch_os_surface(pDirtyPriv->rdpindex);
rdpup_get_pixmap_image_rect(pDirtyPixmap, &id);
rdpup_begin_update();
rdpup_send_alpha_area(&id, 0, 0, pDirtyPixmap->drawable.width,
pDirtyPixmap->drawable.height);
rdpup_end_update();
rdpup_switch_os_surface(-1);
return 0;
}
/******************************************************************************/
int
rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
@ -2256,3 +2446,58 @@ rdpup_draw_text(int font, int flags, int mixmode,
return 0;
}
/******************************************************************************/
int
rdpup_composite(short srcidx, int srcformat, short srcwidth, CARD8 srcrepeat,
PictTransform* srctransform, CARD8 mskflags,
short mskidx, int mskformat, short mskwidth, CARD8 mskrepeat,
CARD8 op, short srcx, short srcy, short mskx, short msky,
short dstx, short dsty, short width, short height,
int dstformat)
{
if (g_connected)
{
LLOGLN(10, (" rdpup_composite"));
rdpup_pre_check(84);
out_uint16_le(g_out_s, 33);
out_uint16_le(g_out_s, 84); /* size */
g_count++;
out_uint16_le(g_out_s, srcidx);
out_uint32_le(g_out_s, srcformat);
out_uint16_le(g_out_s, srcwidth);
out_uint8(g_out_s, srcrepeat);
if (srctransform == 0)
{
out_uint8s(g_out_s, 10 * 4);
}
else
{
out_uint32_le(g_out_s, 1);
out_uint32_le(g_out_s, srctransform->matrix[0][0]);
out_uint32_le(g_out_s, srctransform->matrix[0][1]);
out_uint32_le(g_out_s, srctransform->matrix[0][2]);
out_uint32_le(g_out_s, srctransform->matrix[1][0]);
out_uint32_le(g_out_s, srctransform->matrix[1][1]);
out_uint32_le(g_out_s, srctransform->matrix[1][2]);
out_uint32_le(g_out_s, srctransform->matrix[2][0]);
out_uint32_le(g_out_s, srctransform->matrix[2][1]);
out_uint32_le(g_out_s, srctransform->matrix[2][2]);
}
out_uint8(g_out_s, mskflags);
out_uint16_le(g_out_s, mskidx);
out_uint32_le(g_out_s, mskformat);
out_uint16_le(g_out_s, mskwidth);
out_uint8(g_out_s, mskrepeat);
out_uint8(g_out_s, op);
out_uint16_le(g_out_s, srcx);
out_uint16_le(g_out_s, srcy);
out_uint16_le(g_out_s, mskx);
out_uint16_le(g_out_s, msky);
out_uint16_le(g_out_s, dstx);
out_uint16_le(g_out_s, dsty);
out_uint16_le(g_out_s, width);
out_uint16_le(g_out_s, height);
out_uint32_le(g_out_s, dstformat);
}
return 0;
}

@ -283,6 +283,20 @@ xrdp_painter_copy(struct xrdp_painter* self,
int x, int y, int cx, int cy,
int srcx, int srcy);
int APP_CC
xrdp_painter_composite(struct xrdp_painter* self,
struct xrdp_bitmap* src,
int srcformat,
int srcwidth,
int srcrepeat,
struct xrdp_bitmap* dst,
int* srctransform,
int mskflags,
struct xrdp_bitmap* msk,
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);
int APP_CC
xrdp_painter_line(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
int x1, int y1, int x2, int y2);
@ -374,6 +388,16 @@ int DEFAULT_CC
server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy);
int DEFAULT_CC
server_paint_rect_bpp(struct xrdp_mod* mod, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy,
int bpp);
int DEFAULT_CC
server_composite(struct xrdp_mod* mod, 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);
int DEFAULT_CC
server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask);
int DEFAULT_CC
@ -434,6 +458,9 @@ int DEFAULT_CC
server_create_os_surface(struct xrdp_mod* mod, int id,
int width, int height);
int DEFAULT_CC
server_create_os_surface_bpp(struct xrdp_mod* mod, int id,
int width, int height, int bpp);
int DEFAULT_CC
server_switch_os_surface(struct xrdp_mod* mod, int id);
int DEFAULT_CC
server_delete_os_surface(struct xrdp_mod* mod, int id);

@ -239,7 +239,7 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
}
else
{
log_message(LOG_LEVEL_ERROR,"error in xrdp_cache_add_bitmap, too big(%d)", bmp_size);
log_message(LOG_LEVEL_ERROR,"error in xrdp_cache_add_bitmap, too big(%d) bpp %d", bmp_size, bitmap->bpp);
}
/* look for oldest */

@ -414,6 +414,9 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_notify_delete = server_notify_delete;
self->mod->server_monitored_desktop = server_monitored_desktop;
self->mod->server_add_char_alpha = server_add_char_alpha;
self->mod->server_create_os_surface_bpp = server_create_os_surface_bpp;
self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite;
}
}
@ -906,7 +909,6 @@ xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
struct stream* s;
int order_type;
int rv = 0;
struct rail_window_state_order rwso;
s = trans_get_in_s(trans);
if (s == 0)
@ -1057,7 +1059,7 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port)
self->usechansrv = 1;
/* connect channel redir */
if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
{
/* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
@ -2058,6 +2060,79 @@ server_paint_rect(struct xrdp_mod *mod, int x, int y, int cx, int cy,
return 0;
}
/*****************************************************************************/
int DEFAULT_CC
server_paint_rect_bpp(struct xrdp_mod* mod, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy,
int bpp)
{
struct xrdp_wm* wm;
struct xrdp_bitmap* b;
struct xrdp_painter* p;
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
b = xrdp_bitmap_create_with_data(width, height, bpp, data, wm);
xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy);
xrdp_bitmap_delete(b);
return 0;
}
/*****************************************************************************/
int DEFAULT_CC
server_composite(struct xrdp_mod* mod, 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_wm* wm;
struct xrdp_bitmap* b;
struct xrdp_bitmap* msk;
struct xrdp_painter* p;
struct xrdp_os_bitmap_item* bi;
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
b = 0;
msk = 0;
bi = xrdp_cache_get_os_bitmap(wm->cache, srcidx);
if (bi != 0)
{
b = bi->bitmap;
}
if (mskflags & 1)
{
bi = xrdp_cache_get_os_bitmap(wm->cache, mskidx);
if (bi != 0)
{
msk = bi->bitmap;
}
}
if (b != 0)
{
xrdp_painter_composite(p, b, srcformat, srcwidth, srcrepeat,
wm->target_surface, srctransform,
mskflags, msk, mskformat, mskwidth, mskrepeat,
op, srcx, srcy, mskx, msky, dstx, dsty,
width, height, dstformat);
}
else
{
g_writeln("server_composite: error finding id %d or %d", srcidx, mskidx);
}
return 0;
}
/*****************************************************************************/
int DEFAULT_CC
server_set_pointer(struct xrdp_mod *mod, int x, int y,
@ -2673,6 +2748,29 @@ server_create_os_surface(struct xrdp_mod *mod, int rdpindex,
return 0;
}
/*****************************************************************************/
int DEFAULT_CC
server_create_os_surface_bpp(struct xrdp_mod* mod, int rdpindex,
int width, int height, int bpp)
{
struct xrdp_wm* wm;
struct xrdp_bitmap* bitmap;
int error;
wm = (struct xrdp_wm*)(mod->wm);
bitmap = xrdp_bitmap_create(width, height, bpp,
WND_TYPE_OFFSCREEN, wm);
error = xrdp_cache_add_os_bitmap(wm->cache, bitmap, rdpindex);
if (error != 0)
{
g_writeln("server_create_os_surface_bpp: xrdp_cache_add_os_bitmap failed");
return 1;
}
bitmap->item_index = rdpindex;
bitmap->id = rdpindex;
return 0;
}
/*****************************************************************************/
int DEFAULT_CC
server_switch_os_surface(struct xrdp_mod *mod, int rdpindex)

@ -849,7 +849,7 @@ xrdp_painter_copy(struct xrdp_painter *self,
{
w = MIN(64, ((srcx + cx) - i));
h = MIN(64, ((srcy + cy) - j));
b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm);
b = xrdp_bitmap_create(w, h, src->bpp, 0, self->wm);
xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h);
bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints);
cache_id = HIWORD(bitmap_id);
@ -887,6 +887,86 @@ xrdp_painter_copy(struct xrdp_painter *self,
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_painter_composite(struct xrdp_painter* self,
struct xrdp_bitmap* src,
int srcformat,
int srcwidth,
int srcrepeat,
struct xrdp_bitmap* dst,
int* srctransform,
int mskflags,
struct xrdp_bitmap* msk,
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 clip_rect;
struct xrdp_rect draw_rect;
struct xrdp_rect rect1;
struct xrdp_rect rect2;
struct xrdp_region* region;
int k;
int dx;
int dy;
int palette_id;
int cache_srcidx;
int cache_mskidx;
if (self == 0 || src == 0 || dst == 0)
{
return 0;
}
/* todo data */
if (dst->type == WND_TYPE_BITMAP)
{
return 0;
}
if (src->type == WND_TYPE_OFFSCREEN)
{
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
xrdp_region_add_rect(region, &clip_rect);
dstx += dx;
dsty += dy;
palette_id = 0;
cache_srcidx = src->item_index;
cache_mskidx = -1;
if (mskflags & 1)
{
if (msk != 0)
{
cache_mskidx = msk->item_index; // todo
}
}
k = 0;
while (xrdp_region_get_rect(region, k, &rect1) == 0)
{
if (rect_intersect(&rect1, &clip_rect, &rect2))
{
MAKERECT(rect1, dstx, dsty, width, height);
if (rect_intersect(&rect2, &rect1, &draw_rect))
{
libxrdp_orders_composite_blt(self->session, cache_srcidx, srcformat, srcwidth,
srcrepeat, srctransform, mskflags, cache_mskidx,
mskformat, mskwidth, mskrepeat, op, srcx, srcy,
mskx, msky, dstx, dsty, width, height, dstformat,
&draw_rect);
}
}
k++;
}
xrdp_region_delete(region);
}
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_painter_line(struct xrdp_painter *self,

@ -52,8 +52,10 @@ struct xrdp_mod
int (*server_screen_blt)(struct xrdp_mod* v, int x, int y, int cx, int cy,
int srcx, int srcy);
int (*server_paint_rect)(struct xrdp_mod* v, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy);
int (*server_set_pointer)(struct xrdp_mod* v, int x, int y, char* data, char* mask);
char* data, int width, int height,
int srcx, int srcy);
int (*server_set_pointer)(struct xrdp_mod* v, int x, int y,
char* data, char* mask);
int (*server_palette)(struct xrdp_mod* v, int* palette);
int (*server_msg)(struct xrdp_mod* v, char* msg, int code);
int (*server_is_term)(struct xrdp_mod* v);
@ -122,7 +124,19 @@ struct xrdp_mod
int offset, int baseline,
int width, int height, char* data);
long server_dumby[100 - 39]; /* align, 100 minus the number of server
int (*server_create_os_surface_bpp)(struct xrdp_mod* v, int rdpindex,
int width, int height, int bpp);
int (*server_paint_rect_bpp)(struct xrdp_mod* v, int x, int y, int cx, int cy,
char* data, int width, int height,
int srcx, int srcy, int bpp);
int (*server_composite)(struct xrdp_mod* v, 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);
long server_dumby[100 - 42]; /* align, 100 minus the number of server
functions above */
/* common */
long handle; /* pointer to self as int */

@ -541,12 +541,17 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
int cy;
int srcx;
int srcy;
int mskx;
int msky;
int dstx;
int dsty;
int len_bmpdata;
int style;
int x1;
int y1;
int x2;
int y2;
int bpp;
int rdpid;
int hints;
int mask;
@ -567,6 +572,18 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
int box_top;
int box_right;
int box_bottom;
int srcrepeat;
int srcidx;
int srcformat;
int srcwidth;
int mskflags;
int mskidx;
int mskformat;
int mskwidth;
int mskrepeat;
int dstformat;
int op;
int transform[10];
char *bmpdata;
char cur_data[32 * (32 * 3)];
char cur_mask[32 * (32 / 8)];
@ -734,6 +751,56 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
clip_right, clip_bottom, box_left, box_top,
box_right, box_bottom, x, y, bmpdata, len_bmpdata);
break;
case 31: /* server_create_os_surface_bpp */
in_uint32_le(s, rdpid);
in_uint16_le(s, width);
in_uint16_le(s, height);
in_uint8(s, bpp);
rv = mod->server_create_os_surface_bpp(mod, rdpid, width, height, bpp);
break;
case 32: /* server_paint_rect_bpp */
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, cx);
in_uint16_le(s, cy);
in_uint32_le(s, len_bmpdata);
in_uint8p(s, bmpdata, len_bmpdata);
in_uint16_le(s, width);
in_uint16_le(s, height);
in_sint16_le(s, srcx);
in_sint16_le(s, srcy);
in_uint8(s, bpp);
rv = mod->server_paint_rect_bpp(mod, x, y, cx, cy,
bmpdata, width, height,
srcx, srcy, bpp);
break;
case 33:
in_uint16_le(s, srcidx);
in_uint32_le(s, srcformat);
in_uint16_le(s, srcwidth);
in_uint8(s, srcrepeat);
g_memcpy(transform, s->p, 40);
in_uint8s(s, 40);
in_uint8(s, mskflags);
in_uint16_le(s, mskidx);
in_uint32_le(s, mskformat);
in_uint16_le(s, mskwidth);
in_uint8(s, mskrepeat);
in_uint8(s, op);
in_sint16_le(s, srcx);
in_sint16_le(s, srcy);
in_sint16_le(s, mskx);
in_sint16_le(s, msky);
in_sint16_le(s, dstx);
in_sint16_le(s, dsty);
in_uint16_le(s, width);
in_uint16_le(s, height);
in_uint32_le(s, dstformat);
rv = mod->server_composite(mod, srcidx, srcformat, srcwidth, srcrepeat,
transform, mskflags, mskidx, mskformat,
mskwidth, mskrepeat, op, srcx, srcy, mskx, msky,
dstx, dsty, width, height, dstformat);
break;
case 51: /* server_set_pointer_ex */
rv = process_server_set_pointer_ex(mod, s);
break;

@ -53,7 +53,8 @@ struct mod
int (*server_screen_blt)(struct mod* v, int x, int y, int cx, int cy,
int srcx, int srcy);
int (*server_paint_rect)(struct mod* v, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy);
char* data, int width, int height,
int srcx, int srcy);
int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct mod* v, int* palette);
int (*server_msg)(struct mod* v, char* msg, int code);
@ -122,8 +123,18 @@ struct mod
int (*server_add_char_alpha)(struct mod* v, int font, int charactor,
int offset, int baseline,
int width, int height, char* data);
int (*server_create_os_surface_bpp)(struct mod* v, int rdpindex,
int width, int height, int bpp);
int (*server_paint_rect_bpp)(struct mod* v, int x, int y, int cx, int cy,
char* data, int width, int height,
int srcx, int srcy, int bpp);
int (*server_composite)(struct mod* v, 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);
tbus server_dumby[100 - 39]; /* align, 100 minus the number of server
tbus server_dumby[100 - 42]; /* align, 100 minus the number of server
functions above */
/* common */
tbus handle; /* pointer to self as long */

Loading…
Cancel
Save