This part of work will enable Xephyr to run xcompmgr. The logic is when an X clients wants to get a DRI2Drawable, we create a host peer invisible window, and give the client the peer DRI2Drawable. When glXSwapbuffer happens, we copy the peer window content into Xpehyr managed window and damage that window.
>From 7ed842905c53d7862144f9ec9ccb904d7189e83a Mon Sep 17 00:00:00 2001 From: Haitao Feng <[email protected]> Date: Tue, 11 May 2010 14:29:56 +0800 Subject: Make xcompmgr work Signed-off-by: Haitao Feng <[email protected]> --- 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 _______________________________________________ MeeGo-dev mailing list [email protected] http://lists.meego.com/listinfo/meego-dev
