summaryrefslogtreecommitdiffstats
path: root/xorg
diff options
context:
space:
mode:
authorJim Grandy <jgrandy@authentic8.com>2013-07-07 08:17:12 -0700
committerJim Grandy <jgrandy@authentic8.com>2013-08-22 12:54:14 -0700
commit648470afa1eea156d8501b247363d8e754ab8e88 (patch)
tree42f9e4c684730090058e43232b02965c7ff99493 /xorg
parent981741f55c61dadb680418c9d3f35b5a3291eb0e (diff)
downloadxrdp-proprietary-648470afa1eea156d8501b247363d8e754ab8e88.tar.gz
xrdp-proprietary-648470afa1eea156d8501b247363d8e754ab8e88.zip
Add xorg/X11R7.6/rdp/rdpComposite.c, missed from previous commit (a27cbdd)
Diffstat (limited to 'xorg')
-rw-r--r--xorg/X11R7.6/rdp/rdpComposite.c908
1 files changed, 908 insertions, 0 deletions
diff --git a/xorg/X11R7.6/rdp/rdpComposite.c b/xorg/X11R7.6/rdp/rdpComposite.c
new file mode 100644
index 00000000..8528c4c6
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpComposite.c
@@ -0,0 +1,908 @@
+/*
+ Copyright 2012-2013 Jay Sorg
+
+ Permission to use, copy, modify, distribute, and sell this software and its
+ documentation for any purpose is hereby granted without fee, provided that
+ the above copyright notice appear in all copies and that both that
+ copyright notice and this permission notice appear in supporting
+ documentation.
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 0
+
+#define LOG_LEVEL 1
+#define LLOG(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0)
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_can_do_pix_to_pix; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+extern int g_do_glyph_cache; /* in rdpmain.c */
+extern int g_doing_font; /* in rdpmain.c */
+extern int g_do_composite; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+extern int g_crc_seed; /* in rdpmisc.c */
+extern int g_crc_table[]; /* in rdpmisc.c */
+
+/******************************************************************************/
+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;
+}
+
+/******************************************************************************/
+static int
+print_format(PictFormatShort format)
+{
+ switch (format)
+ {
+ case PIXMAN_a2r10g10b10:
+ LLOGLN(0, (" PIXMAN_x2r10g10b10"));
+ break;
+ case PIXMAN_x2r10g10b10:
+ LLOGLN(0, (" PIXMAN_x2r10g10b10"));
+ break;
+ case PIXMAN_a2b10g10r10:
+ LLOGLN(0, (" PIXMAN_a2b10g10r10"));
+ break;
+ case PIXMAN_x2b10g10r10:
+ LLOGLN(0, (" PIXMAN_x2b10g10r10"));
+ break;
+
+ case PIXMAN_a8r8g8b8:
+ LLOGLN(0, (" PIXMAN_a8r8g8b8"));
+ break;
+ case PIXMAN_x8r8g8b8:
+ LLOGLN(0, (" PIXMAN_x8r8g8b8"));
+ break;
+ case PIXMAN_a8b8g8r8:
+ LLOGLN(0, (" PIXMAN_a8b8g8r8"));
+ break;
+ case PIXMAN_x8b8g8r8:
+ LLOGLN(0, (" PIXMAN_x8b8g8r8"));
+ break;
+ case PIXMAN_b8g8r8a8:
+ LLOGLN(0, (" PIXMAN_b8g8r8a8"));
+ break;
+ case PIXMAN_b8g8r8x8:
+ LLOGLN(0, (" PIXMAN_b8g8r8x8"));
+ break;
+
+ /* 24bpp formats */
+ case PIXMAN_r8g8b8:
+ LLOGLN(0, (" PIXMAN_r8g8b8"));
+ break;
+ case PIXMAN_b8g8r8:
+ LLOGLN(0, (" PIXMAN_b8g8r8"));
+ break;
+
+ /* 16bpp formats */
+ case PIXMAN_r5g6b5:
+ LLOGLN(0, (" PIXMAN_r5g6b5"));
+ break;
+ case PIXMAN_b5g6r5:
+ LLOGLN(0, (" PIXMAN_b5g6r5"));
+ break;
+
+ case PIXMAN_a1r5g5b5:
+ LLOGLN(0, (" PIXMAN_a1r5g5b5"));
+ break;
+ case PIXMAN_x1r5g5b5:
+ LLOGLN(0, (" PIXMAN_x1r5g5b5"));
+ break;
+ case PIXMAN_a1b5g5r5:
+ LLOGLN(0, (" PIXMAN_a1b5g5r5"));
+ break;
+ case PIXMAN_x1b5g5r5:
+ LLOGLN(0, (" PIXMAN_x1b5g5r5"));
+ break;
+ case PIXMAN_a4r4g4b4:
+ LLOGLN(0, (" PIXMAN_a4r4g4b4"));
+ break;
+ case PIXMAN_x4r4g4b4:
+ LLOGLN(0, (" PIXMAN_x4r4g4b4"));
+ break;
+ case PIXMAN_a4b4g4r4:
+ LLOGLN(0, (" PIXMAN_a4b4g4r4"));
+ break;
+ case PIXMAN_x4b4g4r4:
+ LLOGLN(0, (" PIXMAN_x4b4g4r4"));
+ break;
+
+ /* 8bpp formats */
+ case PIXMAN_a8:
+ LLOGLN(0, (" PIXMAN_a8"));
+ break;
+ case PIXMAN_r3g3b2:
+ LLOGLN(0, (" PIXMAN_r3g3b2"));
+ break;
+ case PIXMAN_b2g3r3:
+ LLOGLN(0, (" PIXMAN_b2g3r3"));
+ break;
+ case PIXMAN_a2r2g2b2:
+ LLOGLN(0, (" PIXMAN_a2r2g2b2"));
+ break;
+ case PIXMAN_a2b2g2r2:
+ LLOGLN(0, (" PIXMAN_a2b2g2r2"));
+ break;
+
+ case PIXMAN_c8:
+ LLOGLN(0, (" PIXMAN_c8"));
+ break;
+ case PIXMAN_g8:
+ LLOGLN(0, (" PIXMAN_g8"));
+ break;
+
+ case PIXMAN_x4a4:
+ LLOGLN(0, (" PIXMAN_x4a4"));
+ break;
+
+ /* 4bpp formats */
+ case PIXMAN_a4:
+ LLOGLN(0, (" PIXMAN_a4"));
+ break;
+ case PIXMAN_r1g2b1:
+ LLOGLN(0, (" PIXMAN_r1g2b1"));
+ break;
+ case PIXMAN_b1g2r1:
+ LLOGLN(0, (" PIXMAN_b1g2r1"));
+ break;
+ case PIXMAN_a1r1g1b1:
+ LLOGLN(0, (" PIXMAN_a1r1g1b1"));
+ break;
+ case PIXMAN_a1b1g1r1:
+ LLOGLN(0, (" PIXMAN_a1b1g1r1"));
+ break;
+
+ case PIXMAN_c4:
+ LLOGLN(0, (" PIXMAN_c4"));
+ break;
+ case PIXMAN_g4:
+ LLOGLN(0, (" PIXMAN_g4"));
+ break;
+
+ /* 1bpp formats */
+ case PIXMAN_a1:
+ LLOGLN(0, (" PIXMAN_a1"));
+ break;
+ case PIXMAN_g1:
+ LLOGLN(0, (" PIXMAN_g1"));
+ break;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+static int
+compsoite_print(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+ INT16 yDst, CARD16 width, CARD16 height)
+{
+ PixmapPtr pSrcPixmap;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pSrcPriv;
+ rdpPixmapRec* pDstPriv;
+
+ LLOGLN(0, ("compsoite_print: op %d xSrc %d ySrc %d xDst %d yDst %d "
+ "width %d height %d",
+ op, xSrc, ySrc, xDst, yDst, width, height));
+
+ if (pSrc != 0)
+ {
+ LLOGLN(0, (" src depth %d width %d height %d repeat %d repeatType %d "
+ "dither %d filter %d alphaMap %p componentAlpha %d", pSrc->pDrawable->depth,
+ pSrc->pDrawable->width, pSrc->pDrawable->height,
+ pSrc->repeat, pSrc->repeatType, pSrc->dither, pSrc->filter,
+ pSrc->alphaMap, pSrc->componentAlpha));
+ LLOGLN(0, (" transform %p", pSrc->transform));
+ LLOGLN(0, (" detail format red %d red mask %d green %d green mask %d "
+ "blue %d blue mask %d",
+ pSrc->pFormat->direct.red, pSrc->pFormat->direct.redMask,
+ pSrc->pFormat->direct.green, pSrc->pFormat->direct.greenMask,
+ pSrc->pFormat->direct.blue, pSrc->pFormat->direct.blueMask));
+ print_format(pSrc->format);
+ if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pSrcPixmap = (PixmapPtr)(pSrc->pDrawable);
+ pSrcPriv = GETPIXPRIV(pSrcPixmap);
+ LLOGLN(0, (" DRAWABLE_PIXMAP pSrcPriv %p status %d", pSrcPriv, pSrcPriv->status));
+ }
+ else if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ LLOGLN(0, (" DRAWABLE_WINDOW"));
+ }
+ else
+ {
+ LLOGLN(0, (" OTHER"));
+ }
+ }
+ if (pMask != 0)
+ {
+ LLOGLN(0, (" msk depth %d width %d height %d repeat %d repeatType %d",
+ pMask->pDrawable->depth,
+ pMask->pDrawable->width,
+ pMask->pDrawable->height, pMask->repeat, pMask->repeatType));
+ print_format(pMask->format);
+ }
+ if (pDst != 0)
+ {
+ LLOGLN(0, (" dst depth %d width %d height %d repeat %d repeatType %d "
+ "dither %d filter %d alphaMap %p", pDst->pDrawable->depth,
+ pDst->pDrawable->width, pDst->pDrawable->height,
+ pDst->repeat, pDst->repeatType, pDst->dither, pDst->filter,
+ pDst->alphaMap));
+ LLOGLN(0, (" transform %p", pDst->transform));
+ print_format(pDst->format);
+ if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)(pDst->pDrawable);
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ LLOGLN(0, (" DRAWABLE_PIXMAP pDstPriv %p status %d", pDstPriv, pDstPriv->status));
+ }
+ else if (pDst->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ LLOGLN(0, (" DRAWABLE_WINDOW"));
+ }
+ else
+ {
+ LLOGLN(0, (" OTHER"));
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+static int
+src_alpha_needed(CARD8 op)
+{
+ int rv;
+
+ rv = 0;
+ switch (op)
+ {
+ case 3: /* Over */
+ case 6: /* InReverse */
+ case 8: /* OutReverse */
+ case 9: /* Atop */
+ case 10: /* AtopReverse */
+ case 11: /* Xor */
+ case 13: /* Saturate */
+ case 17: /* DisjointOver */
+ case 18: /* DisjointOverReverse */
+ case 19: /* DisjointIn */
+ case 20: /* DisjointInReverse */
+ case 21: /* DisjointOut */
+ case 22: /* DisjointOutReverse */
+ case 23: /* DisjointAtop */
+ case 24: /* DisjointAtopReverse */
+ case 25: /* DisjointXor */
+ case 29: /* ConjointOver */
+ case 30: /* ConjointOverReverse */
+ case 31: /* ConjointIn */
+ case 32: /* ConjointInReverse */
+ case 33: /* ConjointOut */
+ case 34: /* ConjointOutReverse */
+ case 35: /* ConjointAtop */
+ case 36: /* ConjointAtopReverse */
+ case 37: /* ConjointXor */
+ rv = 1;
+ break;
+ }
+ return rv;
+}
+
+/******************************************************************************/
+static int
+dst_alpha_needed(CARD8 op)
+{
+ int rv;
+
+ rv = 0;
+ switch (op)
+ {
+ case 4: /* OverReverse */
+ case 5: /* In */
+ case 7: /* Out */
+ case 9: /* Atop */
+ case 10: /* AtopReverse */
+ case 11: /* Xor */
+ case 13: /* Saturate */
+ case 17: /* DisjointOver */
+ case 18: /* DisjointOverReverse */
+ case 19: /* DisjointIn */
+ case 20: /* DisjointInReverse */
+ case 21: /* DisjointOut */
+ case 22: /* DisjointOutReverse */
+ case 23: /* DisjointAtop */
+ case 24: /* DisjointAtopReverse */
+ case 25: /* DisjointXor */
+ case 29: /* ConjointOver */
+ case 30: /* ConjointOverReverse */
+ case 31: /* ConjointIn */
+ case 32: /* ConjointInReverse */
+ case 33: /* ConjointOut */
+ case 34: /* ConjointOutReverse */
+ case 35: /* ConjointAtop */
+ case 36: /* ConjointAtopReverse */
+ case 37: /* ConjointXor */
+ rv = 1;
+ break;
+ }
+ return rv;
+}
+
+struct msk_info
+{
+ int flags;
+ int idx;
+ int format;
+ int width;
+ int repeat;
+};
+
+static char g_com_fail_strings[][128] =
+{
+ "OK",
+ "src not remotable",
+ "dst not remotable",
+ "msk not remotable"
+};
+
+/******************************************************************************/
+/* returns boolean */
+static int
+check_drawables(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+ INT16 yDst, CARD16 width, CARD16 height, struct msk_info* msk)
+{
+ int rv;
+ int fail_reason;
+ PixmapPtr pSrcPixmap;
+ PixmapPtr pDstPixmap;
+ PixmapPtr pMskPixmap;
+ rdpPixmapRec* pSrcPriv;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pMskPriv;
+
+ fail_reason = 0;
+ pSrcPixmap = 0;
+ pDstPixmap = 0;
+ pMskPixmap = 0;
+ pSrcPriv = 0;
+ pDstPriv = 0;
+ pMskPriv = 0;
+ rv = 0;
+ if (pSrc != 0)
+ {
+ if (pSrc->pDrawable != 0)
+ {
+ if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pSrcPixmap = (PixmapPtr)(pSrc->pDrawable);
+ pSrcPriv = GETPIXPRIV(pSrcPixmap);
+ if (xrdp_is_os(pSrcPixmap, pSrcPriv))
+ {
+ if (pDst != 0)
+ {
+ if (pDst->pDrawable != 0)
+ {
+ if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)(pDst->pDrawable);
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (xrdp_is_os(pDstPixmap, pDstPriv))
+ {
+ rv = 1;
+ }
+ else
+ {
+ fail_reason = 2;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ fail_reason = 1;
+ }
+ }
+ }
+ }
+ if (rv)
+ {
+ if (pMask != 0)
+ {
+#if 1
+ rv = 0;
+ if (pMask->pDrawable != 0)
+ {
+ if (pMask->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pMskPixmap = (PixmapPtr)(pMask->pDrawable);
+ pMskPriv = GETPIXPRIV(pMskPixmap);
+ if (xrdp_is_os(pMskPixmap, pMskPriv))
+ {
+ rv = 1;
+ msk->flags = 1;
+ msk->idx = pMskPriv->rdpindex;
+ msk->format = pMask->format;
+ msk->width = pMask->pDrawable->width;
+ msk->repeat = pMask->repeatType;
+ }
+ else
+ {
+ fail_reason = 3;
+ }
+ }
+ }
+#endif
+ }
+ }
+ if (rv != 0)
+ {
+ /* TODO: figure out why source XRGB does not work
+ skipping for now because they rarely happen
+ happens when drawing Firefox open file dialog, the button icons */
+ if (PIXMAN_FORMAT_A(pSrc->format) == 0)
+ {
+ rv = 0;
+ LLOGLN(10, ("check_drawables: src format"));
+ }
+ }
+ if (rv == 0)
+ {
+ LLOGLN(10, ("check_drawables: can not remote [%s]", g_com_fail_strings[fail_reason]));
+#if 0
+ compsoite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+#endif
+ }
+ else
+ {
+ LLOGLN(10, ("check_drawables: can remote [%s]", g_com_fail_strings[fail_reason]));
+#if 0
+ compsoite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+#endif
+ }
+ return rv;
+}
+
+/******************************************************************************/
+static int
+rdpRemoteComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+ INT16 yDst, CARD16 width, CARD16 height)
+{
+ int ok_to_remote;
+ PixmapPtr pSrcPixmap;
+ PixmapPtr pMskPixmap;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pSrcPriv;
+ rdpPixmapRec* pMskPriv;
+ rdpPixmapRec* pDstPriv;
+ BoxRec box;
+ RegionRec reg1;
+ RegionRec reg2;
+ DrawablePtr p;
+ int j;
+ int num_clips;
+ struct msk_info msk;
+
+ LLOGLN(10, ("rdpRemoteComposite:"));
+
+ memset(&msk, 0, sizeof(msk));
+ ok_to_remote = check_drawables(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height,
+ &msk);
+ if (!ok_to_remote)
+ {
+ return 1;
+ }
+
+ ValidatePicture(pSrc);
+ pSrcPixmap = (PixmapPtr)(pSrc->pDrawable);
+ pSrcPriv = GETPIXPRIV(pSrcPixmap);
+ rdpup_check_dirty(pSrcPixmap, pSrcPriv);
+ if (PIXMAN_FORMAT_A(pSrc->format) > 0)
+ {
+ if (src_alpha_needed(op))
+ {
+ rdpup_check_alpha_dirty(pSrcPixmap, pSrcPriv);
+ }
+ }
+
+ ValidatePicture(pDst);
+ pDstPixmap = (PixmapPtr)(pDst->pDrawable);
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ rdpup_check_dirty(pDstPixmap, pDstPriv);
+
+ if (PIXMAN_FORMAT_A(pDst->format) > 0)
+ {
+ if (dst_alpha_needed(op))
+ {
+ rdpup_check_alpha_dirty(pDstPixmap, pDstPriv);
+ }
+ }
+
+ if (pMask != 0)
+ {
+ ValidatePicture(pMask);
+ pMskPixmap = (PixmapPtr)(pMask->pDrawable);
+ pMskPriv = GETPIXPRIV(pMskPixmap);
+ rdpup_check_dirty(pMskPixmap, pMskPriv);
+ if (PIXMAN_FORMAT_A(msk.format) > 0)
+ {
+ rdpup_check_alpha_dirty(pMskPixmap, pMskPriv);
+ }
+ }
+
+ p = pDst->pDrawable;
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ if (pDst->pCompositeClip != 0)
+ {
+ box.x1 = xDst;
+ box.y1 = 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);
+ RegionTranslate(&reg1, p->x, p->y);
+ num_clips = REGION_NUM_RECTS(&reg1);
+ if (num_clips > 0)
+ {
+ LLOGLN(10, ("num_clips %d", num_clips));
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg1)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ LLOGLN(10, ("pSrc->format 0x%x 0x%x 0x%x %d %d %d %d %d %d %d %d",
+ pSrc->format, msk.format, pDst->format, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height));
+ rdpup_composite(pSrcPriv->rdpindex, pSrc->format,
+ pSrc->pDrawable->width, pSrc->repeatType,
+ pSrc->transform, msk.flags, msk.idx, msk.format,
+ msk.width, msk.repeat, op, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height, pDst->format);
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
+ }
+ RegionUninit(&reg1);
+ RegionUninit(&reg2);
+ }
+ else
+ {
+ rdpup_begin_update();
+ rdpup_composite(pSrcPriv->rdpindex, pSrc->format,
+ pSrc->pDrawable->width, pSrc->repeatType,
+ pSrc->transform, msk.flags, msk.idx, msk.format,
+ msk.width, msk.repeat, op, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height, pDst->format);
+ rdpup_end_update();
+ }
+ rdpup_switch_os_surface(-1);
+
+ return 0;
+}
+
+/******************************************************************************/
+static void
+rdpCompositeOrg(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+ INT16 yDst, CARD16 width, CARD16 height)
+{
+ PictureScreenPtr ps;
+
+ 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;
+}
+
+/******************************************************************************/
+/* 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;
+ 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:"));
+
+ if (g_doing_font == 2)
+ {
+ rdpCompositeOrg(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+
+ return;
+ }
+
+#if 0
+ if (g_do_glyph_cache && g_do_alpha_glyphs)
+ {
+ if (pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1)
+ {
+ if (pMask != 0)
+ {
+ /* TODO: here we can try to send it as a gylph */
+ }
+ }
+ }
+#endif
+
+ /* try to remote the composite call */
+ if (g_do_composite &&
+ rdpRemoteComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height) == 0)
+ {
+ rdpCompositeOrg(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ return;
+ }
+
+ rdpCompositeOrg(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+
+ LLOGLN(10, ("rdpComposite: op %d %p %p %p w %d h %d", op, pSrc, pMask, pDst, width, height));
+
+ p = pDst->pDrawable;
+
+ pDstPriv = 0;
+ 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(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;
+ 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;
+ rdpGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs);
+ ps = GetPictureScreen(g_pScreen);
+ ps->Glyphs = g_rdpScreen.Glyphs;
+ ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ nlists, lists, glyphs);
+ ps->Glyphs = rdpGlyphs;
+ }
+ 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"));
+}