Make xcompmgr work

Haitao Feng haitao.feng at intel.com
Mon May 10 23:29:56 PDT 2010


Signed-off-by: Haitao Feng <haitao.feng at intel.com>
---
 configure.ac                   |    3 +++
 hw/kdrive/ephyr/ephyr.c        |   35 +++++++++++++++++++++++++++++++++++
 hw/kdrive/ephyr/ephyrdri2ext.c |    2 ++
 hw/kdrive/ephyr/hostx.c        |   37 +++++++++++++++++++++++++++++++++++--
 4 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6110d8c..04624a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2052,6 +2052,9 @@ if test "$KDRIVE" = yes; then
     if test "x$DRI" = xyes && test "x$GLX" = xyes; then
         XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
     fi
+    if test "x$DRI2" = xyes && test "x$GLX" = xyes; then
+        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xcomposite"
+    fi
 
     PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"])
     if test "x$XEPHYR" = xauto; then
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 53ec272..82573d7 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -923,6 +923,41 @@ ephyrExposePairedWindow (int a_remote)
 }
 #endif /* XF86DRI */
 
+#ifdef DRI2
+void
+ephyrPaintPairedLocalWindow (int a_remote, int depth, char *data, int sx, int sy, int width, int height)
+{
+    EphyrDRI2WindowPair *pair = NULL;
+    RegionRec reg;
+    ScreenPtr screen;
+    GCPtr pGC;
+    XID gcval = FALSE;
+    int status;
+
+    if (!findDRI2WindowPairFromRemote (a_remote, &pair)) {
+        EPHYR_LOG ("did not find a pair for this window\n");
+        return;
+    }
+
+    screen = pair->local->drawable.pScreen;
+
+    pGC = CreateGC((DrawablePtr)pair->local,
+                   GCGraphicsExposures, &gcval,
+                   &status, (XID)0, serverClient);
+    if (pGC) {
+        FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+
+        REGION_NULL (screen, &reg);
+        REGION_COPY (screen, &reg, &pair->local->clipList);
+        pGC->pCompositeClip = &reg;
+        pPriv->pm = -1;
+        pGC->ops->PutImage((DrawablePtr)pair->local, pGC, depth, 0, 0, width, height, 0, ZPixmap, data);
+        DamageRegionAppend((DrawablePtr)pair->local, &reg);
+        REGION_UNINIT (screen, &reg);
+    }
+}
+#endif
+
 void
 ephyrPoll(void)
 {
diff --git a/hw/kdrive/ephyr/ephyrdri2ext.c b/hw/kdrive/ephyr/ephyrdri2ext.c
index 099d2ad..a7112eb 100644
--- a/hw/kdrive/ephyr/ephyrdri2ext.c
+++ b/hw/kdrive/ephyr/ephyrdri2ext.c
@@ -1101,6 +1101,8 @@ ProcDRI2CopyRegion(ClientPtr client)
     if (status != Success)
 	return status;
 
+    hostx_copy_region(stuff->drawable, pair, pRegion, pDrawable->x, pDrawable->y);
+
     /* CopyRegion needs to be a round trip to make sure the X server
      * queues the swap buffer rendering commands before the DRI client
      * continues rendering.  The reply has a bitmask to signal the
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index ed3550a..4ebdce9 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -57,10 +57,12 @@
 #include <X11/keysym.h>
 #include <X11/extensions/XShm.h>
 #include <X11/extensions/shape.h>
-
 #if defined(XF86DRI) || defined(DRI2)
 #include <GL/glx.h>
 #endif /* XF86DRI */
+#if DRI2
+#include <X11/extensions/Xcomposite.h>
+#endif
 #include "ephyrlog.h"
 #include "ephyrdri2ext.h"
 
@@ -1171,6 +1173,32 @@ out:
 
 }
 
+#if DRI2
+int
+hostx_copy_region (XID drawable,
+                       EphyrDRI2WindowPair *pair,
+                       RegionPtr pRegion,
+                       int sx,
+                       int sy)
+{
+    Display *dpy=hostx_get_display () ;
+    XImage *img;
+    int width, height;
+
+    width  = pRegion->extents.x2 - pRegion->extents.x1;
+    height = pRegion->extents.y2 - pRegion->extents.y1;
+
+    img = XGetImage(dpy, pair->remote, 0, 0, width, height, 0xffffffff, ZPixmap);
+
+    if (img){
+        ephyrPaintPairedLocalWindow(pair->remote, img->depth, img->data, sx, sy, width, height);
+        XDestroyImage(img);
+    }
+
+    return 0;
+}
+#endif
+
 int
 hostx_create_window (int a_screen_number,
                      EphyrBox *a_geometry,
@@ -1206,12 +1234,14 @@ hostx_create_window (int a_screen_number,
                                                   visual_info->screen),
                                       visual_info->visual,
                                       AllocNone) ;
+#ifndef DRI2
     attrs.event_mask = ButtonPressMask
                        |ButtonReleaseMask
                        |PointerMotionMask
                        |KeyPressMask
                        |KeyReleaseMask
                        |ExposureMask;
+#endif
     winmask = CWColormap|CWEventMask;
 
     win = XCreateWindow (dpy, hostx_get_window (a_screen_number),
@@ -1224,13 +1254,16 @@ hostx_create_window (int a_screen_number,
         goto out ;
     }
     if (HostX.screens[a_screen_number].peer_win == None) {
-	HostX.screens[a_screen_number].peer_win = win;
+        HostX.screens[a_screen_number].peer_win = win;
     } else {
         EPHYR_LOG_ERROR ("multiple peer windows created for same screen\n") ;
     }
     XFlush (dpy) ;
     XMapWindow (dpy, win) ;
     *a_host_peer = win ;
+#if DRI2
+    XCompositeRedirectWindow (dpy, win, CompositeRedirectManual);
+#endif
     is_ok = TRUE ;
 out:
     EPHYR_LOG ("leave\n") ;
-- 
1.6.3.3



More information about the xorg-devel mailing list