summaryrefslogtreecommitdiffstats
path: root/xorg
diff options
context:
space:
mode:
authorJim Grandy <jgrandy@authentic8.com>2013-07-06 21:03:58 -0700
committerJim Grandy <jgrandy@authentic8.com>2013-08-22 12:54:10 -0700
commit981741f55c61dadb680418c9d3f35b5a3291eb0e (patch)
treed7323da59200fb65719a21cea0e650e6efac62d9 /xorg
parent71e8136e41b1a6c32fa2507f8df3b2c36ba9fd1e (diff)
downloadxrdp-proprietary-981741f55c61dadb680418c9d3f35b5a3291eb0e.tar.gz
xrdp-proprietary-981741f55c61dadb680418c9d3f35b5a3291eb0e.zip
Hand-apply patch (compositing) from Authentic8: 5d5e470 81c9c29 b0c2c10 27d8a01 a96a217 e512090 a9a6762 9c02bfa bd26fcc c0d29d9 676dd35 3b26737
Diffstat (limited to 'xorg')
-rw-r--r--xorg/X11R7.6/rdp/Makefile2
-rw-r--r--xorg/X11R7.6/rdp/rdp.h33
-rw-r--r--xorg/X11R7.6/rdp/rdpdraw.c390
-rw-r--r--xorg/X11R7.6/rdp/rdpglyph.c1
-rw-r--r--xorg/X11R7.6/rdp/rdpmain.c4
-rw-r--r--xorg/X11R7.6/rdp/rdpup.c255
6 files changed, 394 insertions, 291 deletions
diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile
index 8d07e100..b38d27c0 100644
--- a/xorg/X11R7.6/rdp/Makefile
+++ b/xorg/X11R7.6/rdp/Makefile
@@ -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
diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h
index 3a36ade9..234737fb 100644
--- a/xorg/X11R7.6/rdp/rdp.h
+++ b/xorg/X11R7.6/rdp/rdp.h
@@ -282,6 +282,8 @@ struct rdp_draw_item
union urdp_draw_item u;
};
+#define XRDP_USE_COUNT_THRESHOLD 1
+
struct _rdpPixmapRec
{
int status;
@@ -289,6 +291,11 @@ struct _rdpPixmapRec
int con_number;
int is_dirty;
int is_scratch;
+ 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 +453,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 +558,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 +576,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 +592,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);
@@ -671,6 +697,13 @@ struct stream
}
/******************************************************************************/
+#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) \
{ \
diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c
index dec945ee..d1f83179 100644
--- a/xorg/X11R7.6/rdp/rdpdraw.c
+++ b/xorg/X11R7.6/rdp/rdpdraw.c
@@ -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;
}
@@ -943,6 +987,7 @@ 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;
@@ -996,6 +1041,64 @@ xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv)
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)
+{
+ RegionRec reg1;
+ BoxRec box;
+ int width;
+ int height;
+ struct image_data id;
if (!XRDP_IS_OS(priv))
{
@@ -1527,284 +1630,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(10, ("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"));
-}
diff --git a/xorg/X11R7.6/rdp/rdpglyph.c b/xorg/X11R7.6/rdp/rdpglyph.c
index 3da30737..e6e011be 100644
--- a/xorg/X11R7.6/rdp/rdpglyph.c
+++ b/xorg/X11R7.6/rdp/rdpglyph.c
@@ -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)
{
diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c
index 281c3e38..20fe437d 100644
--- a/xorg/X11R7.6/rdp/rdpmain.c
+++ b/xorg/X11R7.6/rdp/rdpmain.c
@@ -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;
@@ -63,6 +64,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;
diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c
index f97096f5..958a7d92 100644
--- a/xorg/X11R7.6/rdp/rdpup.c
+++ b/xorg/X11R7.6/rdp/rdpup.c
@@ -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;
}
/******************************************************************************/
@@ -1280,6 +1305,25 @@ convert_pixels(void *src, void *dst, int num_pixels)
/******************************************************************************/
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)
{
if (g_connected)
@@ -1451,6 +1495,26 @@ rdpup_create_os_surface(int rdpindex, int width, int height)
/******************************************************************************/
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)
{
LLOGLN(10, ("rdpup_switch_os_surface:"));
@@ -1654,7 +1718,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;
@@ -1706,6 +1770,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,
int rdpindex, int srcx, int srcy)
@@ -2176,6 +2337,35 @@ rdpup_check_dirty_screen(rdpPixmapRec *pDirtyPriv)
/******************************************************************************/
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,
char* bmpdata, int bmpdata_bytes)
{
@@ -2257,3 +2447,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;
+}