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, ®);
+ REGION_COPY (screen, ®, &pair->local->clipList);
+ pGC->pCompositeClip = ®
+ pPriv->pm = -1;
+ pGC->ops->PutImage((DrawablePtr)pair->local, pGC, depth, 0, 0, width, height, 0, ZPixmap, data);
+ DamageRegionAppend((DrawablePtr)pair->local, ®);
+ REGION_UNINIT (screen, ®);
+ }
+}
+#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