diff options
Diffstat (limited to 'xorg-server/hw/kdrive/ephyr')
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr.c | 20 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr_draw.c | 1047 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrdriext.c | 2858 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrglxext.c | 1446 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c | 2024 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrvideo.c | 2546 |
6 files changed, 4970 insertions, 4971 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c index 6e61b8c5d..21c696c20 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr.c @@ -76,13 +76,13 @@ ephyrCardInit (KdCardInfo *card) {
EphyrPriv *priv;
- priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv));
+ priv = (EphyrPriv *) malloc(sizeof (EphyrPriv));
if (!priv)
return FALSE;
if (!ephyrInitialize (card, priv))
{
- xfree (priv);
+ free(priv);
return FALSE;
}
card->driver = priv;
@@ -188,7 +188,7 @@ ephyrScreenInit (KdScreenInfo *screen) {
EphyrScrPriv *scrpriv;
- scrpriv = xcalloc (1, sizeof (EphyrScrPriv));
+ scrpriv = calloc(1, sizeof (EphyrScrPriv));
if (!scrpriv)
return FALSE;
@@ -198,7 +198,7 @@ ephyrScreenInit (KdScreenInfo *screen) if (!ephyrScreenInitialize (screen, scrpriv))
{
screen->driver = 0;
- xfree (scrpriv);
+ free(scrpriv);
return FALSE;
}
@@ -740,7 +740,7 @@ ephyrScreenFini (KdScreenInfo *screen) if (scrpriv->shadow) {
KdShadowFbFree (screen);
}
- xfree(screen->driver);
+ free(screen->driver);
screen->driver = NULL;
}
@@ -1034,7 +1034,7 @@ void ephyrCardFini (KdCardInfo *card)
{
EphyrPriv *priv = card->driver;
- xfree (priv);
+ free(priv);
}
void
@@ -1086,11 +1086,11 @@ static Status MouseInit (KdPointerInfo *pi)
{
pi->driverPrivate = (EphyrPointerPrivate *)
- xcalloc(sizeof(EphyrPointerPrivate), 1);
+ calloc(sizeof(EphyrPointerPrivate), 1);
((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
pi->nAxes = 3;
pi->nButtons = 32;
- xfree(pi->name);
+ free(pi->name);
pi->name = strdup("Xephyr virtual mouse");
ephyrMouse = pi;
return Success;
@@ -1132,7 +1132,7 @@ static Status EphyrKeyboardInit (KdKeyboardInfo *ki)
{
ki->driverPrivate = (EphyrKbdPrivate *)
- xcalloc(sizeof(EphyrKbdPrivate), 1);
+ calloc(sizeof(EphyrKbdPrivate), 1);
hostx_load_keymap();
if (!ephyrKeySyms.map) {
ErrorF("Couldn't load keymap from host\n");
@@ -1140,7 +1140,7 @@ EphyrKeyboardInit (KdKeyboardInfo *ki) }
ki->minScanCode = ephyrKeySyms.minKeyCode;
ki->maxScanCode = ephyrKeySyms.maxKeyCode;
- xfree(ki->name);
+ free(ki->name);
ki->name = strdup("Xephyr virtual keyboard");
ephyrKbd = ki;
return Success;
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_draw.c b/xorg-server/hw/kdrive/ephyr/ephyr_draw.c index f9fac8007..f3e2be6eb 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr_draw.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr_draw.c @@ -1,524 +1,523 @@ -/* - * Copyright © 2006 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * - */ - -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif - -#include "ephyr.h" -#include "exa_priv.h" -#include "fbpict.h" - -#define EPHYR_TRACE_DRAW 0 - -#if EPHYR_TRACE_DRAW -#define TRACE_DRAW() ErrorF("%s\n", __FUNCTION__); -#else -#define TRACE_DRAW() do { } while (0) -#endif - -/* Use some oddball alignments, to expose issues in alignment handling in EXA. */ -#define EPHYR_OFFSET_ALIGN 24 -#define EPHYR_PITCH_ALIGN 24 - -#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024) -#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024) - -/** - * Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to - * fb functions. - */ -static void -ephyrPreparePipelinedAccess(PixmapPtr pPix, int index) -{ - KdScreenPriv(pPix->drawable.pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - assert(fakexa->saved_ptrs[index] == NULL); - fakexa->saved_ptrs[index] = pPix->devPrivate.ptr; - - if (pPix->devPrivate.ptr != NULL) - return; - - pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix); -} - -/** - * Restores the original devPrivate.ptr of the pixmap from before we messed with - * it. - */ -static void -ephyrFinishPipelinedAccess(PixmapPtr pPix, int index) -{ - KdScreenPriv(pPix->drawable.pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - pPix->devPrivate.ptr = fakexa->saved_ptrs[index]; - fakexa->saved_ptrs[index] = NULL; -} - -/** - * Sets up a scratch GC for fbFill, and saves other parameters for the - * ephyrSolid implementation. - */ -static Bool -ephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) -{ - ScreenPtr pScreen = pPix->drawable.pScreen; - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - CARD32 tmpval[3]; - - ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST); - - fakexa->pDst = pPix; - fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen); - - tmpval[0] = alu; - tmpval[1] = pm; - tmpval[2] = fg; - ChangeGC(fakexa->pGC, GCFunction | GCPlaneMask | GCForeground, - tmpval); - - ValidateGC(&pPix->drawable, fakexa->pGC); - - TRACE_DRAW(); - - return TRUE; -} - -/** - * Does an fbFill of the rectangle to be drawn. - */ -static void -ephyrSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2) -{ - ScreenPtr pScreen = pPix->drawable.pScreen; - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - fbFill(&fakexa->pDst->drawable, fakexa->pGC, x1, y1, x2 - x1, y2 - y1); -} - -/** - * Cleans up the scratch GC created in ephyrPrepareSolid. - */ -static void -ephyrDoneSolid(PixmapPtr pPix) -{ - ScreenPtr pScreen = pPix->drawable.pScreen; - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - FreeScratchGC(fakexa->pGC); - - ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST); -} - -/** - * Sets up a scratch GC for fbCopyArea, and saves other parameters for the - * ephyrCopy implementation. - */ -static Bool -ephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, - Pixel pm) -{ - ScreenPtr pScreen = pDst->drawable.pScreen; - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - CARD32 tmpval[2]; - - ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); - ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); - - fakexa->pSrc = pSrc; - fakexa->pDst = pDst; - fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen); - - tmpval[0] = alu; - tmpval[1] = pm; - ChangeGC (fakexa->pGC, GCFunction | GCPlaneMask, tmpval); - - ValidateGC(&pDst->drawable, fakexa->pGC); - - TRACE_DRAW(); - - return TRUE; -} - -/** - * Does an fbCopyArea to take care of the requested copy. - */ -static void -ephyrCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, int w, int h) -{ - ScreenPtr pScreen = pDst->drawable.pScreen; - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - fbCopyArea(&fakexa->pSrc->drawable, &fakexa->pDst->drawable, fakexa->pGC, - srcX, srcY, w, h, dstX, dstY); -} - -/** - * Cleans up the scratch GC created in ephyrPrepareCopy. - */ -static void -ephyrDoneCopy(PixmapPtr pDst) -{ - ScreenPtr pScreen = pDst->drawable.pScreen; - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - FreeScratchGC (fakexa->pGC); - - ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC); - ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST); -} - -/** - * Reports that we can always accelerate the given operation. This may not be - * desirable from an EXA testing standpoint -- testing the fallback paths would - * be useful, too. - */ -static Bool -ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, - PicturePtr pDstPicture) -{ - /* Exercise the component alpha helper, so fail on this case like a normal - * driver - */ - if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver) - return FALSE; - - return TRUE; -} - -/** - * Saves off the parameters for ephyrComposite. - */ -static Bool -ephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, - PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, - PixmapPtr pDst) -{ - KdScreenPriv(pDst->drawable.pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); - ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); - if (pMask != NULL) - ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK); - - fakexa->op = op; - fakexa->pSrcPicture = pSrcPicture; - fakexa->pMaskPicture = pMaskPicture; - fakexa->pDstPicture = pDstPicture; - fakexa->pSrc = pSrc; - fakexa->pMask = pMask; - fakexa->pDst = pDst; - - TRACE_DRAW(); - - return TRUE; -} - -/** - * Does an fbComposite to complete the requested drawing operation. - */ -static void -ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, - int dstX, int dstY, int w, int h) -{ - KdScreenPriv(pDst->drawable.pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture, - fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY, - w, h); -} - -static void -ephyrDoneComposite(PixmapPtr pDst) -{ - KdScreenPriv(pDst->drawable.pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - if (fakexa->pMask != NULL) - ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK); - ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC); - ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST); -} - -/** - * Does fake acceleration of DownloadFromScren using memcpy. - */ -static Bool -ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, - int dst_pitch) -{ - KdScreenPriv(pSrc->drawable.pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - unsigned char *src; - int src_pitch, cpp; - - if (pSrc->drawable.bitsPerPixel < 8) - return FALSE; - - ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); - - cpp = pSrc->drawable.bitsPerPixel / 8; - src_pitch = exaGetPixmapPitch(pSrc); - src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc); - src += y * src_pitch + x * cpp; - - for (; h > 0; h--) { - memcpy(dst, src, w * cpp); - dst += dst_pitch; - src += src_pitch; - } - - exaMarkSync(pSrc->drawable.pScreen); - - ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC); - - return TRUE; -} - -/** - * Does fake acceleration of UploadToScreen using memcpy. - */ -static Bool -ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, - int src_pitch) -{ - KdScreenPriv(pDst->drawable.pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - unsigned char *dst; - int dst_pitch, cpp; - - if (pDst->drawable.bitsPerPixel < 8) - return FALSE; - - ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); - - cpp = pDst->drawable.bitsPerPixel / 8; - dst_pitch = exaGetPixmapPitch(pDst); - dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst); - dst += y * dst_pitch + x * cpp; - - for (; h > 0; h--) { - memcpy(dst, src, w * cpp); - dst += dst_pitch; - src += src_pitch; - } - - exaMarkSync(pDst->drawable.pScreen); - - ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST); - - return TRUE; -} - -static Bool -ephyrPrepareAccess(PixmapPtr pPix, int index) -{ - /* Make sure we don't somehow end up with a pointer that is in framebuffer - * and hasn't been readied for us. - */ - assert(pPix->devPrivate.ptr != NULL); - - return TRUE; -} - -/** - * In fakexa, we currently only track whether we have synced to the latest - * "accelerated" drawing that has happened or not. It's not used for anything - * yet. - */ -static int -ephyrMarkSync(ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - fakexa->is_synced = FALSE; - - return 0; -} - -/** - * Assumes that we're waiting on the latest marker. When EXA gets smarter and - * starts using markers in a fine-grained way (for example, waiting on drawing - * to required pixmaps to complete, rather than waiting for all drawing to - * complete), we'll want to make the ephyrMarkSync/ephyrWaitMarker - * implementation fine-grained as well. - */ -static void -ephyrWaitMarker(ScreenPtr pScreen, int marker) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrFakexaPriv *fakexa = scrpriv->fakexa; - - fakexa->is_synced = TRUE; -} - -/** - * This function initializes EXA to use the fake acceleration implementation - * which just falls through to software. The purpose is to have a reliable, - * correct driver with which to test changes to the EXA core. - */ -Bool -ephyrDrawInit(ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - EphyrPriv *priv = screen->card->driver; - EphyrFakexaPriv *fakexa; - Bool success; - - fakexa = xcalloc(1, sizeof(*fakexa)); - if (fakexa == NULL) - return FALSE; - - fakexa->exa = exaDriverAlloc(); - if (fakexa->exa == NULL) { - xfree(fakexa); - return FALSE; - } - - fakexa->exa->memoryBase = (CARD8 *) (priv->base); - fakexa->exa->memorySize = priv->bytes_per_line * ephyrBufferHeight(screen); - fakexa->exa->offScreenBase = priv->bytes_per_line * screen->height; - - /* Since we statically link against EXA, we shouldn't have to be smart about - * versioning. - */ - fakexa->exa->exa_major = 2; - fakexa->exa->exa_minor = 0; - - fakexa->exa->PrepareSolid = ephyrPrepareSolid; - fakexa->exa->Solid = ephyrSolid; - fakexa->exa->DoneSolid = ephyrDoneSolid; - - fakexa->exa->PrepareCopy = ephyrPrepareCopy; - fakexa->exa->Copy = ephyrCopy; - fakexa->exa->DoneCopy = ephyrDoneCopy; - - fakexa->exa->CheckComposite = ephyrCheckComposite; - fakexa->exa->PrepareComposite = ephyrPrepareComposite; - fakexa->exa->Composite = ephyrComposite; - fakexa->exa->DoneComposite = ephyrDoneComposite; - - fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen; - fakexa->exa->UploadToScreen = ephyrUploadToScreen; - - fakexa->exa->MarkSync = ephyrMarkSync; - fakexa->exa->WaitMarker = ephyrWaitMarker; - - fakexa->exa->PrepareAccess = ephyrPrepareAccess; - - fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN; - fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN; - - fakexa->exa->maxX = 1023; - fakexa->exa->maxY = 1023; - - fakexa->exa->flags = EXA_OFFSCREEN_PIXMAPS; - - success = exaDriverInit(pScreen, fakexa->exa); - if (success) { - ErrorF("Initialized fake EXA acceleration\n"); - scrpriv->fakexa = fakexa; - } else { - ErrorF("Failed to initialize EXA\n"); - xfree(fakexa->exa); - xfree(fakexa); - } - - return success; -} - -void -ephyrDrawEnable(ScreenPtr pScreen) -{ -} - -void -ephyrDrawDisable(ScreenPtr pScreen) -{ -} - -void -ephyrDrawFini(ScreenPtr pScreen) -{ -} - -/** - * exaDDXDriverInit is required by the top-level EXA module, and is used by - * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since - * we won't be enabling/disabling the FB. - */ -void -exaDDXDriverInit(ScreenPtr pScreen) -{ - ExaScreenPriv(pScreen); - - pExaScr->migration = ExaMigrationSmart; - pExaScr->checkDirtyCorrectness = TRUE; -} +/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "ephyr.h"
+#include "exa_priv.h"
+#include "fbpict.h"
+
+#define EPHYR_TRACE_DRAW 0
+
+#if EPHYR_TRACE_DRAW
+#define TRACE_DRAW() ErrorF("%s\n", __FUNCTION__);
+#else
+#define TRACE_DRAW() do { } while (0)
+#endif
+
+/* Use some oddball alignments, to expose issues in alignment handling in EXA. */
+#define EPHYR_OFFSET_ALIGN 24
+#define EPHYR_PITCH_ALIGN 24
+
+#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024)
+#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024)
+
+/**
+ * Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to
+ * fb functions.
+ */
+static void
+ephyrPreparePipelinedAccess(PixmapPtr pPix, int index)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ assert(fakexa->saved_ptrs[index] == NULL);
+ fakexa->saved_ptrs[index] = pPix->devPrivate.ptr;
+
+ if (pPix->devPrivate.ptr != NULL)
+ return;
+
+ pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix);
+}
+
+/**
+ * Restores the original devPrivate.ptr of the pixmap from before we messed with
+ * it.
+ */
+static void
+ephyrFinishPipelinedAccess(PixmapPtr pPix, int index)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ pPix->devPrivate.ptr = fakexa->saved_ptrs[index];
+ fakexa->saved_ptrs[index] = NULL;
+}
+
+/**
+ * Sets up a scratch GC for fbFill, and saves other parameters for the
+ * ephyrSolid implementation.
+ */
+static Bool
+ephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ ChangeGCVal tmpval[3];
+
+ ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST);
+
+ fakexa->pDst = pPix;
+ fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+
+ tmpval[0].val = alu;
+ tmpval[1].val = pm;
+ tmpval[2].val = fg;
+ ChangeGC(NullClient, fakexa->pGC, GCFunction | GCPlaneMask | GCForeground, tmpval);
+
+ ValidateGC(&pPix->drawable, fakexa->pGC);
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbFill of the rectangle to be drawn.
+ */
+static void
+ephyrSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbFill(&fakexa->pDst->drawable, fakexa->pGC, x1, y1, x2 - x1, y2 - y1);
+}
+
+/**
+ * Cleans up the scratch GC created in ephyrPrepareSolid.
+ */
+static void
+ephyrDoneSolid(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ FreeScratchGC(fakexa->pGC);
+
+ ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST);
+}
+
+/**
+ * Sets up a scratch GC for fbCopyArea, and saves other parameters for the
+ * ephyrCopy implementation.
+ */
+static Bool
+ephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu,
+ Pixel pm)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ ChangeGCVal tmpval[2];
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ fakexa->pSrc = pSrc;
+ fakexa->pDst = pDst;
+ fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen);
+
+ tmpval[0].val = alu;
+ tmpval[1].val = pm;
+ ChangeGC (NullClient, fakexa->pGC, GCFunction | GCPlaneMask, tmpval);
+
+ ValidateGC(&pDst->drawable, fakexa->pGC);
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbCopyArea to take care of the requested copy.
+ */
+static void
+ephyrCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, int w, int h)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbCopyArea(&fakexa->pSrc->drawable, &fakexa->pDst->drawable, fakexa->pGC,
+ srcX, srcY, w, h, dstX, dstY);
+}
+
+/**
+ * Cleans up the scratch GC created in ephyrPrepareCopy.
+ */
+static void
+ephyrDoneCopy(PixmapPtr pDst)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ FreeScratchGC (fakexa->pGC);
+
+ ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
+ ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
+}
+
+/**
+ * Reports that we can always accelerate the given operation. This may not be
+ * desirable from an EXA testing standpoint -- testing the fallback paths would
+ * be useful, too.
+ */
+static Bool
+ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ /* Exercise the component alpha helper, so fail on this case like a normal
+ * driver
+ */
+ if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * Saves off the parameters for ephyrComposite.
+ */
+static Bool
+ephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask,
+ PixmapPtr pDst)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+ if (pMask != NULL)
+ ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK);
+
+ fakexa->op = op;
+ fakexa->pSrcPicture = pSrcPicture;
+ fakexa->pMaskPicture = pMaskPicture;
+ fakexa->pDstPicture = pDstPicture;
+ fakexa->pSrc = pSrc;
+ fakexa->pMask = pMask;
+ fakexa->pDst = pDst;
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbComposite to complete the requested drawing operation.
+ */
+static void
+ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int w, int h)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture,
+ fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY,
+ w, h);
+}
+
+static void
+ephyrDoneComposite(PixmapPtr pDst)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ if (fakexa->pMask != NULL)
+ ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK);
+ ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
+ ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
+}
+
+/**
+ * Does fake acceleration of DownloadFromScren using memcpy.
+ */
+static Bool
+ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
+ int dst_pitch)
+{
+ KdScreenPriv(pSrc->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ unsigned char *src;
+ int src_pitch, cpp;
+
+ if (pSrc->drawable.bitsPerPixel < 8)
+ return FALSE;
+
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ cpp = pSrc->drawable.bitsPerPixel / 8;
+ src_pitch = exaGetPixmapPitch(pSrc);
+ src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc);
+ src += y * src_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+
+ exaMarkSync(pSrc->drawable.pScreen);
+
+ ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ return TRUE;
+}
+
+/**
+ * Does fake acceleration of UploadToScreen using memcpy.
+ */
+static Bool
+ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ unsigned char *dst;
+ int dst_pitch, cpp;
+
+ if (pDst->drawable.bitsPerPixel < 8)
+ return FALSE;
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+
+ cpp = pDst->drawable.bitsPerPixel / 8;
+ dst_pitch = exaGetPixmapPitch(pDst);
+ dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst);
+ dst += y * dst_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+
+ exaMarkSync(pDst->drawable.pScreen);
+
+ ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST);
+
+ return TRUE;
+}
+
+static Bool
+ephyrPrepareAccess(PixmapPtr pPix, int index)
+{
+ /* Make sure we don't somehow end up with a pointer that is in framebuffer
+ * and hasn't been readied for us.
+ */
+ assert(pPix->devPrivate.ptr != NULL);
+
+ return TRUE;
+}
+
+/**
+ * In fakexa, we currently only track whether we have synced to the latest
+ * "accelerated" drawing that has happened or not. It's not used for anything
+ * yet.
+ */
+static int
+ephyrMarkSync(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fakexa->is_synced = FALSE;
+
+ return 0;
+}
+
+/**
+ * Assumes that we're waiting on the latest marker. When EXA gets smarter and
+ * starts using markers in a fine-grained way (for example, waiting on drawing
+ * to required pixmaps to complete, rather than waiting for all drawing to
+ * complete), we'll want to make the ephyrMarkSync/ephyrWaitMarker
+ * implementation fine-grained as well.
+ */
+static void
+ephyrWaitMarker(ScreenPtr pScreen, int marker)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fakexa->is_synced = TRUE;
+}
+
+/**
+ * This function initializes EXA to use the fake acceleration implementation
+ * which just falls through to software. The purpose is to have a reliable,
+ * correct driver with which to test changes to the EXA core.
+ */
+Bool
+ephyrDrawInit(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrPriv *priv = screen->card->driver;
+ EphyrFakexaPriv *fakexa;
+ Bool success;
+
+ fakexa = calloc(1, sizeof(*fakexa));
+ if (fakexa == NULL)
+ return FALSE;
+
+ fakexa->exa = exaDriverAlloc();
+ if (fakexa->exa == NULL) {
+ free(fakexa);
+ return FALSE;
+ }
+
+ fakexa->exa->memoryBase = (CARD8 *) (priv->base);
+ fakexa->exa->memorySize = priv->bytes_per_line * ephyrBufferHeight(screen);
+ fakexa->exa->offScreenBase = priv->bytes_per_line * screen->height;
+
+ /* Since we statically link against EXA, we shouldn't have to be smart about
+ * versioning.
+ */
+ fakexa->exa->exa_major = 2;
+ fakexa->exa->exa_minor = 0;
+
+ fakexa->exa->PrepareSolid = ephyrPrepareSolid;
+ fakexa->exa->Solid = ephyrSolid;
+ fakexa->exa->DoneSolid = ephyrDoneSolid;
+
+ fakexa->exa->PrepareCopy = ephyrPrepareCopy;
+ fakexa->exa->Copy = ephyrCopy;
+ fakexa->exa->DoneCopy = ephyrDoneCopy;
+
+ fakexa->exa->CheckComposite = ephyrCheckComposite;
+ fakexa->exa->PrepareComposite = ephyrPrepareComposite;
+ fakexa->exa->Composite = ephyrComposite;
+ fakexa->exa->DoneComposite = ephyrDoneComposite;
+
+ fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen;
+ fakexa->exa->UploadToScreen = ephyrUploadToScreen;
+
+ fakexa->exa->MarkSync = ephyrMarkSync;
+ fakexa->exa->WaitMarker = ephyrWaitMarker;
+
+ fakexa->exa->PrepareAccess = ephyrPrepareAccess;
+
+ fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN;
+ fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN;
+
+ fakexa->exa->maxX = 1023;
+ fakexa->exa->maxY = 1023;
+
+ fakexa->exa->flags = EXA_OFFSCREEN_PIXMAPS;
+
+ success = exaDriverInit(pScreen, fakexa->exa);
+ if (success) {
+ ErrorF("Initialized fake EXA acceleration\n");
+ scrpriv->fakexa = fakexa;
+ } else {
+ ErrorF("Failed to initialize EXA\n");
+ free(fakexa->exa);
+ free(fakexa);
+ }
+
+ return success;
+}
+
+void
+ephyrDrawEnable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyrDrawDisable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyrDrawFini(ScreenPtr pScreen)
+{
+}
+
+/**
+ * exaDDXDriverInit is required by the top-level EXA module, and is used by
+ * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since
+ * we won't be enabling/disabling the FB.
+ */
+void
+exaDDXDriverInit(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+
+ pExaScr->migration = ExaMigrationSmart;
+ pExaScr->checkDirtyCorrectness = TRUE;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c index 5f5fd3bff..3d3d18a39 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c @@ -1,1429 +1,1429 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@openedhand.com> - * - * Copyright © 2007 OpenedHand Ltd - * - * 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, and that the name of OpenedHand Ltd not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. OpenedHand Ltd makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - * This file is heavily copied from hw/xfree86/dri/xf86dri.c - * - * Authors: - * Dodji Seketeli <dodji@openedhand.com> - */ - -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif - -#include <string.h> - -#include <X11/X.h> -#include <X11/Xproto.h> -#define _XF86DRI_SERVER_ -#include <X11/dri/xf86dri.h> -#include <X11/dri/xf86driproto.h> -#include "misc.h" -#include "privates.h" -#include "dixstruct.h" -#include "extnsionst.h" -#include "colormapst.h" -#include "cursorstr.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "servermd.h" -#include "swaprep.h" -#include "ephyrdri.h" -#include "ephyrdriext.h" -#include "hostx.h" -#define _HAVE_XALLOC_DECLS -#include "ephyrlog.h" -#include "protocol-versions.h" - -typedef struct { - int foo; -} EphyrDRIWindowPrivRec; -typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr; - -typedef struct { - CreateWindowProcPtr CreateWindow ; - DestroyWindowProcPtr DestroyWindow ; - MoveWindowProcPtr MoveWindow ; - PositionWindowProcPtr PositionWindow ; - ClipNotifyProcPtr ClipNotify ; -} EphyrDRIScreenPrivRec; -typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr; - -static int DRIErrorBase; - -static DISPATCH_PROC(ProcXF86DRIQueryVersion); -static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable); -static DISPATCH_PROC(ProcXF86DRIOpenConnection); -static DISPATCH_PROC(ProcXF86DRICloseConnection); -static DISPATCH_PROC(ProcXF86DRIGetClientDriverName); -static DISPATCH_PROC(ProcXF86DRICreateContext); -static DISPATCH_PROC(ProcXF86DRIDestroyContext); -static DISPATCH_PROC(ProcXF86DRICreateDrawable); -static DISPATCH_PROC(ProcXF86DRIDestroyDrawable); -static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo); -static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo); -static DISPATCH_PROC(ProcXF86DRIDispatch); -static DISPATCH_PROC(ProcXF86DRIAuthConnection); - -static DISPATCH_PROC(SProcXF86DRIQueryVersion); -static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable); -static DISPATCH_PROC(SProcXF86DRIDispatch); - -static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ; -static Bool ephyrDRICreateWindow (WindowPtr a_win) ; -static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ; -static void ephyrDRIMoveWindow (WindowPtr a_win, - int a_x, int a_y, - WindowPtr a_siblings, - VTKind a_kind); -static Bool ephyrDRIPositionWindow (WindowPtr a_win, - int x, int y) ; -static void ephyrDRIClipNotify (WindowPtr a_win, - int a_x, int a_y) ; - -static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ; -static Bool destroyHostPeerWindow (const WindowPtr a_win) ; -static Bool findWindowPairFromLocal (WindowPtr a_local, - EphyrWindowPair **a_pair); - -static unsigned char DRIReqCode = 0; - -static int ephyrDRIWindowKeyIndex; -static DevPrivateKey ephyrDRIWindowKey = &ephyrDRIWindowKeyIndex; -static int ephyrDRIScreenKeyIndex; -static DevPrivateKey ephyrDRIScreenKey = &ephyrDRIScreenKeyIndex; - -#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \ - dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey)) -#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \ - dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey)) - - -Bool -ephyrDRIExtensionInit (ScreenPtr a_screen) -{ - Bool is_ok=FALSE ; - ExtensionEntry* extEntry=NULL; - EphyrDRIScreenPrivPtr screen_priv=NULL ; - - EPHYR_LOG ("enter\n") ; - if (!hostx_has_dri ()) { - EPHYR_LOG ("host does not have DRI extension\n") ; - goto out ; - } - EPHYR_LOG ("host X does have DRI extension\n") ; - if (!hostx_has_xshape ()) { - EPHYR_LOG ("host does not have XShape extension\n") ; - goto out ; - } - EPHYR_LOG ("host X does have XShape extension\n") ; - -#ifdef XF86DRI_EVENTS - EventType = CreateNewResourceType (XF86DRIFreeEvents, "DRIEvents"); - if (!EventType) { - EPHYR_LOG_ERROR ("failed to register DRI event resource type\n") ; - goto out ; - } -#endif - - if ((extEntry = AddExtension(XF86DRINAME, - XF86DRINumberEvents, - XF86DRINumberErrors, - ProcXF86DRIDispatch, - SProcXF86DRIDispatch, - NULL, - StandardMinorOpcode))) { - DRIReqCode = (unsigned char)extEntry->base; - DRIErrorBase = extEntry->errorBase; - } else { - EPHYR_LOG_ERROR ("failed to register DRI extension\n") ; - goto out ; - } - screen_priv = xcalloc (1, sizeof (EphyrDRIScreenPrivRec)) ; - if (!screen_priv) { - EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ; - goto out ; - } - dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv); - - if (!ephyrDRIScreenInit (a_screen)) { - EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ; - goto out ; - } - EphyrMirrorHostVisuals (a_screen) ; - is_ok=TRUE ; -out: - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -static Bool -ephyrDRIScreenInit (ScreenPtr a_screen) -{ - Bool is_ok=FALSE ; - EphyrDRIScreenPrivPtr screen_priv=NULL ; - - EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ; - - screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ; - - screen_priv->CreateWindow = a_screen->CreateWindow ; - screen_priv->DestroyWindow = a_screen->DestroyWindow ; - screen_priv->MoveWindow = a_screen->MoveWindow ; - screen_priv->PositionWindow = a_screen->PositionWindow ; - screen_priv->ClipNotify = a_screen->ClipNotify ; - - a_screen->CreateWindow = ephyrDRICreateWindow ; - a_screen->DestroyWindow = ephyrDRIDestroyWindow ; - a_screen->MoveWindow = ephyrDRIMoveWindow ; - a_screen->PositionWindow = ephyrDRIPositionWindow ; - a_screen->ClipNotify = ephyrDRIClipNotify ; - - is_ok = TRUE ; - - return is_ok ; -} - -static Bool -ephyrDRICreateWindow (WindowPtr a_win) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv - && screen_priv->CreateWindow, - FALSE) ; - - EPHYR_LOG ("enter. win:%p\n", a_win) ; - - screen->CreateWindow = screen_priv->CreateWindow ; - is_ok = (*screen->CreateWindow) (a_win) ; - screen->CreateWindow = ephyrDRICreateWindow ; - - if (is_ok) { - dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL); - } - return is_ok ; -} - -static Bool -ephyrDRIDestroyWindow (WindowPtr a_win) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv - && screen_priv->DestroyWindow, - FALSE) ; - - screen->DestroyWindow = screen_priv->DestroyWindow ; - if (screen->DestroyWindow) { - is_ok = (*screen->DestroyWindow) (a_win) ; - } - screen->DestroyWindow = ephyrDRIDestroyWindow ; - - if (is_ok) { - EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (win_priv) { - destroyHostPeerWindow (a_win) ; - xfree (win_priv) ; - dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL); - EPHYR_LOG ("destroyed the remote peer window\n") ; - } - } - return is_ok ; -} - -static void -ephyrDRIMoveWindow (WindowPtr a_win, - int a_x, int a_y, - WindowPtr a_siblings, - VTKind a_kind) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - EphyrDRIWindowPrivPtr win_priv=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrBox geo; - int x=0,y=0;/*coords relative to parent window*/ - - EPHYR_RETURN_IF_FAIL (a_win) ; - - EPHYR_LOG ("enter\n") ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_IF_FAIL (screen) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_IF_FAIL (screen_priv - && screen_priv->MoveWindow) ; - - screen->MoveWindow = screen_priv->MoveWindow ; - if (screen->MoveWindow) { - (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ; - } - screen->MoveWindow = ephyrDRIMoveWindow ; - - EPHYR_LOG ("window: %p\n", a_win) ; - if (!a_win->parent) { - EPHYR_LOG ("cannot move root window\n") ; - is_ok = TRUE ; - goto out ; - } - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (!win_priv) { - EPHYR_LOG ("not a DRI peered window\n") ; - is_ok = TRUE ; - goto out ; - } - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to get window pair\n") ; - goto out ; - } - /*compute position relative to parent window*/ - x = a_win->drawable.x - a_win->parent->drawable.x ; - y = a_win->drawable.y - a_win->parent->drawable.y ; - /*set the geometry to pass to hostx_set_window_geometry*/ - memset (&geo, 0, sizeof (geo)) ; - geo.x = x ; - geo.y = y ; - geo.width = a_win->drawable.width ; - geo.height = a_win->drawable.height ; - hostx_set_window_geometry (pair->remote, &geo) ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; - /*do cleanup here*/ -} - -static Bool -ephyrDRIPositionWindow (WindowPtr a_win, - int a_x, int a_y) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - EphyrDRIWindowPrivPtr win_priv=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrBox geo; - - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - - EPHYR_LOG ("enter\n") ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv - && screen_priv->PositionWindow, - FALSE) ; - - screen->PositionWindow = screen_priv->PositionWindow ; - if (screen->PositionWindow) { - (*screen->PositionWindow) (a_win, a_x, a_y) ; - } - screen->PositionWindow = ephyrDRIPositionWindow ; - - EPHYR_LOG ("window: %p\n", a_win) ; - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (!win_priv) { - EPHYR_LOG ("not a DRI peered window\n") ; - is_ok = TRUE ; - goto out ; - } - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to get window pair\n") ; - goto out ; - } - /*set the geometry to pass to hostx_set_window_geometry*/ - memset (&geo, 0, sizeof (geo)) ; - geo.x = a_x ; - geo.y = a_y ; - geo.width = a_win->drawable.width ; - geo.height = a_win->drawable.height ; - hostx_set_window_geometry (pair->remote, &geo) ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; - /*do cleanup here*/ - return is_ok ; -} - -static void -ephyrDRIClipNotify (WindowPtr a_win, - int a_x, int a_y) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - EphyrDRIWindowPrivPtr win_priv=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrRect *rects=NULL; - int i=0 ; - - EPHYR_RETURN_IF_FAIL (a_win) ; - - EPHYR_LOG ("enter\n") ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_IF_FAIL (screen) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ; - - screen->ClipNotify = screen_priv->ClipNotify ; - if (screen->ClipNotify) { - (*screen->ClipNotify) (a_win, a_x, a_y) ; - } - screen->ClipNotify = ephyrDRIClipNotify ; - - EPHYR_LOG ("window: %p\n", a_win) ; - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (!win_priv) { - EPHYR_LOG ("not a DRI peered window\n") ; - is_ok = TRUE ; - goto out ; - } - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to get window pair\n") ; - goto out ; - } - rects = xcalloc (REGION_NUM_RECTS (&a_win->clipList), - sizeof (EphyrRect)) ; - for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) { - memmove (&rects[i], - ®ION_RECTS (&a_win->clipList)[i], - sizeof (EphyrRect)) ; - rects[i].x1 -= a_win->drawable.x; - rects[i].x2 -= a_win->drawable.x; - rects[i].y1 -= a_win->drawable.y; - rects[i].y2 -= a_win->drawable.y; - } - /* - * push the clipping region of this window - * to the peer window in the host - */ - is_ok = hostx_set_window_bounding_rectangles - (pair->remote, - rects, - REGION_NUM_RECTS (&a_win->clipList)) ; - is_ok = TRUE ; - -out: - xfree (rects) ; - rects = NULL ; - - EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; - /*do cleanup here*/ -} - -/** - * Duplicates a visual of a_screen - * In screen a_screen, for depth a_depth, find a visual which - * bitsPerRGBValue and colormap size equal - * a_bits_per_rgb_values and a_colormap_entries. - * The ID of that duplicated visual is set to a_new_id. - * That duplicated visual is then added to the list of visuals - * of the screen. - */ -static Bool -EphyrDuplicateVisual (unsigned int a_screen, - short a_depth, - short a_class, - short a_bits_per_rgb_values, - short a_colormap_entries, - unsigned int a_red_mask, - unsigned int a_green_mask, - unsigned int a_blue_mask, - unsigned int a_new_id) -{ - Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ; - ScreenPtr screen=NULL ; - VisualRec new_visual, *new_visuals=NULL ; - int i=0 ; - - EPHYR_LOG ("enter\n") ; - if (a_screen > screenInfo.numScreens) { - EPHYR_LOG_ERROR ("bad screen number\n") ; - goto out; - } - memset (&new_visual, 0, sizeof (VisualRec)) ; - - /*get the screen pointed to by a_screen*/ - screen = screenInfo.screens[a_screen] ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - - /* - * In that screen, first look for an existing visual that has the - * same characteristics as those passed in parameter - * to this function and copy it. - */ - for (i=0; i < screen->numVisuals; i++) { - if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values && - screen->visuals[i].ColormapEntries == a_colormap_entries ) { - /*copy the visual found*/ - memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ; - new_visual.vid = a_new_id ; - new_visual.class = a_class ; - new_visual.redMask = a_red_mask ; - new_visual.greenMask = a_green_mask ; - new_visual.blueMask = a_blue_mask ; - found_visual = TRUE ; - EPHYR_LOG ("found a visual that matches visual id: %d\n", - a_new_id) ; - break; - } - } - if (!found_visual) { - EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ; - goto out ; - } - /* - * be prepare to extend screen->visuals to add new_visual to it - */ - new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ; - memmove (new_visuals, - screen->visuals, - screen->numVisuals*sizeof (VisualRec)) ; - memmove (&new_visuals[screen->numVisuals], - &new_visual, - sizeof (VisualRec)) ; - /* - * Now, in that same screen, update the screen->allowedDepths member. - * In that array, each element represents the visuals applicable to - * a given depth. So we need to add an entry matching the new visual - * that we are going to add to screen->visuals - */ - for (i=0; i<screen->numDepths; i++) { - VisualID *vids=NULL; - DepthPtr cur_depth=NULL ; - /*find the entry matching a_depth*/ - if (screen->allowedDepths[i].depth != a_depth) - continue ; - cur_depth = &screen->allowedDepths[i]; - /* - * extend the list of visual IDs in that entry, - * so to add a_new_id in there. - */ - vids = xrealloc (cur_depth->vids, - (cur_depth->numVids+1)*sizeof (VisualID)); - if (!vids) { - EPHYR_LOG_ERROR ("failed to realloc numids\n") ; - goto out ; - } - vids[cur_depth->numVids] = a_new_id ; - /* - * Okay now commit our change. - * Do really update screen->allowedDepths[i] - */ - cur_depth->numVids++ ; - cur_depth->vids = vids ; - found_depth=TRUE; - } - if (!found_depth) { - EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n", - a_screen) ; - goto out ; - } - /* - * Commit our change to screen->visuals - */ - xfree (screen->visuals) ; - screen->visuals = new_visuals ; - screen->numVisuals++ ; - new_visuals = NULL ; - - is_ok = TRUE ; -out: - xfree (new_visuals) ; - new_visuals = NULL ; - - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -/** - * Duplicates the visuals of the host X server. - * This is necessary to have visuals that have the same - * ID as those of the host X. It is important to have that for - * GLX. - */ -static Bool -EphyrMirrorHostVisuals (ScreenPtr a_screen) -{ - Bool is_ok=FALSE; - EphyrHostVisualInfo *visuals=NULL; - int nb_visuals=0, i=0; - - EPHYR_LOG ("enter\n") ; - if (!hostx_get_visuals_info (&visuals, &nb_visuals)) { - EPHYR_LOG_ERROR ("failed to get host visuals\n") ; - goto out ; - } - for (i=0; i<nb_visuals; i++) { - if (!EphyrDuplicateVisual (a_screen->myNum, - visuals[i].depth, - visuals[i].class, - visuals[i].bits_per_rgb, - visuals[i].colormap_size, - visuals[i].red_mask, - visuals[i].green_mask, - visuals[i].blue_mask, - visuals[i].visualid)) { - EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n", - (int)visuals[i].visualid) ; - } - } - - is_ok = TRUE ; -out: - EPHYR_LOG ("leave\n") ; - return is_ok; -} - - -static int -ProcXF86DRIQueryVersion (register ClientPtr client) -{ - xXF86DRIQueryVersionReply rep; - register int n; - REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq); - - EPHYR_LOG ("enter\n") ; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION; - rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION; - rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - swapl(&rep.patchVersion, n); - } - WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client) -{ - xXF86DRIQueryDirectRenderingCapableReply rep; - Bool isCapable; - register int n; - REQUEST(xXF86DRIQueryDirectRenderingCapableReq); - REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) { - return BadValue; - } - rep.isCapable = isCapable; - - if (!LocalClient(client) || client->swapped) - rep.isCapable = 0; - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - - WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - - return (client->noClientException); -} - -static int -ProcXF86DRIOpenConnection (register ClientPtr client) -{ - xXF86DRIOpenConnectionReply rep; - drm_handle_t hSAREA; - char* busIdString; - REQUEST(xXF86DRIOpenConnectionReq); - REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - if (!ephyrDRIOpenConnection(stuff->screen, - &hSAREA, - &busIdString)) { - return BadValue; - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.busIdStringLength = 0; - if (busIdString) - rep.busIdStringLength = strlen(busIdString); - rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) + - pad_to_int32(rep.busIdStringLength)); - - rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff); -#if defined(LONG64) && !defined(__linux__) - rep.hSAREAHigh = (CARD32)(hSAREA >> 32); -#else - rep.hSAREAHigh = 0; -#endif - - WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep); - if (rep.busIdStringLength) - WriteToClient(client, rep.busIdStringLength, busIdString); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIAuthConnection (register ClientPtr client) -{ - xXF86DRIAuthConnectionReply rep; - REQUEST(xXF86DRIAuthConnectionReq); - REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.authenticated = 1; - - if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) { - ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic); - rep.authenticated = 0; - } - WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRICloseConnection (register ClientPtr client) -{ - REQUEST(xXF86DRICloseConnectionReq); - REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq); - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - /* - DRICloseConnection( screenInfo.screens[stuff->screen]); - */ - - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIGetClientDriverName (register ClientPtr client) -{ - xXF86DRIGetClientDriverNameReply rep; - char* clientDriverName; - REQUEST(xXF86DRIGetClientDriverNameReq); - REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - ephyrDRIGetClientDriverName (stuff->screen, - (int *)&rep.ddxDriverMajorVersion, - (int *)&rep.ddxDriverMinorVersion, - (int *)&rep.ddxDriverPatchVersion, - &clientDriverName); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.clientDriverNameLength = 0; - if (clientDriverName) - rep.clientDriverNameLength = strlen(clientDriverName); - rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) - - SIZEOF(xGenericReply) + - pad_to_int32(rep.clientDriverNameLength)); - - WriteToClient(client, - sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep); - if (rep.clientDriverNameLength) - WriteToClient(client, - rep.clientDriverNameLength, - clientDriverName); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRICreateContext (register ClientPtr client) -{ - xXF86DRICreateContextReply rep; - ScreenPtr pScreen; - VisualPtr visual; - int i=0; - unsigned long context_id=0; - REQUEST(xXF86DRICreateContextReq); - REQUEST_SIZE_MATCH(xXF86DRICreateContextReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - pScreen = screenInfo.screens[stuff->screen]; - visual = pScreen->visuals; - - /* Find the requested X visual */ - for (i = 0; i < pScreen->numVisuals; i++, visual++) - if (visual->vid == stuff->visual) - break; - if (i == pScreen->numVisuals) { - /* No visual found */ - return BadValue; - } - - context_id = stuff->context ; - if (!ephyrDRICreateContext (stuff->screen, - stuff->visual, - &context_id, - (drm_context_t *)&rep.hHWContext)) { - return BadValue; - } - - WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIDestroyContext (register ClientPtr client) -{ - REQUEST(xXF86DRIDestroyContextReq); - REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq); - EPHYR_LOG ("enter\n") ; - - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) { - return BadValue; - } - - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static Bool -getWindowVisual (const WindowPtr a_win, - VisualPtr *a_visual) -{ - int i=0, visual_id=0 ; - EPHYR_RETURN_VAL_IF_FAIL (a_win - && a_win->drawable.pScreen - && a_win->drawable.pScreen->visuals, - FALSE) ; - - visual_id = wVisual (a_win) ; - for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) { - if (a_win->drawable.pScreen->visuals[i].vid == visual_id) { - *a_visual = &a_win->drawable.pScreen->visuals[i] ; - return TRUE ; - } - } - return FALSE ; -} - - -#define NUM_WINDOW_PAIRS 256 -static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ; - -static Bool -appendWindowPairToList (WindowPtr a_local, - int a_remote) -{ - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ; - - EPHYR_LOG ("(local,remote):(%p, %d)\n", a_local, a_remote) ; - - for (i=0; i < NUM_WINDOW_PAIRS; i++) { - if (window_pairs[i].local == NULL) { - window_pairs[i].local = a_local ; - window_pairs[i].remote = a_remote ; - return TRUE ; - } - } - return FALSE ; -} - -static Bool -findWindowPairFromLocal (WindowPtr a_local, - EphyrWindowPair **a_pair) -{ - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ; - - for (i=0; i < NUM_WINDOW_PAIRS; i++) { - if (window_pairs[i].local == a_local) { - *a_pair = &window_pairs[i] ; - EPHYR_LOG ("found (%p, %d)\n", - (*a_pair)->local, - (*a_pair)->remote) ; - return TRUE ; - } - } - return FALSE ; -} - -Bool -findWindowPairFromRemote (int a_remote, - EphyrWindowPair **a_pair) -{ - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ; - - for (i=0; i < NUM_WINDOW_PAIRS; i++) { - if (window_pairs[i].remote == a_remote) { - *a_pair = &window_pairs[i] ; - EPHYR_LOG ("found (%p, %d)\n", - (*a_pair)->local, - (*a_pair)->remote) ; - return TRUE ; - } - } - return FALSE ; -} - -static Bool -createHostPeerWindow (const WindowPtr a_win, - int *a_peer_win) -{ - Bool is_ok=FALSE ; - VisualPtr visual=NULL; - EphyrBox geo ; - - EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ; - EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen, - FALSE) ; - - EPHYR_LOG ("enter. a_win '%p'\n", a_win) ; - if (!getWindowVisual (a_win, &visual)) { - EPHYR_LOG_ERROR ("failed to get window visual\n") ; - goto out ; - } - if (!visual) { - EPHYR_LOG_ERROR ("failed to create visual\n") ; - goto out ; - } - memset (&geo, 0, sizeof (geo)) ; - geo.x = a_win->drawable.x ; - geo.y = a_win->drawable.y ; - geo.width = a_win->drawable.width ; - geo.height = a_win->drawable.height ; - if (!hostx_create_window (a_win->drawable.pScreen->myNum, - &geo, visual->vid, a_peer_win)) { - EPHYR_LOG_ERROR ("failed to create host peer window\n") ; - goto out ; - } - if (!appendWindowPairToList (a_win, *a_peer_win)) { - EPHYR_LOG_ERROR ("failed to append window to pair list\n") ; - goto out ; - } - is_ok = TRUE ; -out: - EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ; - return is_ok ; -} - -static Bool -destroyHostPeerWindow (const WindowPtr a_win) -{ - Bool is_ok = FALSE ; - EphyrWindowPair *pair=NULL ; - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to find peer to local window\n") ; - goto out; - } - hostx_destroy_window (pair->remote) ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave\n") ; - return is_ok; -} - -static int -ProcXF86DRICreateDrawable (ClientPtr client) -{ - xXF86DRICreateDrawableReply rep; - DrawablePtr drawable=NULL; - WindowPtr window=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrDRIWindowPrivPtr win_priv=NULL; - int rc=0, remote_win=0; - REQUEST(xXF86DRICreateDrawableReq); - REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - if (drawable->type != DRAWABLE_WINDOW) { - EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ; - return BadImplementation ; - } - EPHYR_LOG ("lookedup drawable %p\n", drawable) ; - window = (WindowPtr)drawable; - if (findWindowPairFromLocal (window, &pair) && pair) { - remote_win = pair->remote ; - EPHYR_LOG ("found window '%p' paire with remote '%d'\n", - window, remote_win) ; - } else if (!createHostPeerWindow (window, &remote_win)) { - EPHYR_LOG_ERROR ("failed to create host peer window\n") ; - return BadAlloc ; - } - - if (!ephyrDRICreateDrawable (stuff->screen, - remote_win, - (drm_drawable_t *)&rep.hHWDrawable)) { - EPHYR_LOG_ERROR ("failed to create dri drawable\n") ; - return BadValue; - } - - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ; - if (!win_priv) { - win_priv = xcalloc (1, sizeof (EphyrDRIWindowPrivRec)) ; - if (!win_priv) { - EPHYR_LOG_ERROR ("failed to allocate window private\n") ; - return BadAlloc ; - } - dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv); - EPHYR_LOG ("paired window '%p' with remote '%d'\n", - window, remote_win) ; - } - - WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIDestroyDrawable (register ClientPtr client) -{ - DrawablePtr drawable=NULL; - WindowPtr window=NULL; - EphyrWindowPair *pair=NULL; - int rc=0; - REQUEST(xXF86DRIDestroyDrawableReq); - REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rc = dixLookupDrawable(&drawable, - stuff->drawable, - client, - 0, - DixReadAccess); - if (rc != Success) - return rc; - if (drawable->type != DRAWABLE_WINDOW) { - EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ; - return BadImplementation ; - } - window = (WindowPtr)drawable; - if (!findWindowPairFromLocal (window, &pair) && pair) { - EPHYR_LOG_ERROR ("failed to find pair window\n") ; - return BadImplementation; - } - if (!ephyrDRIDestroyDrawable(stuff->screen, - pair->remote/*drawable in host x*/)) { - EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ; - return BadImplementation; - } - pair->local=NULL ; - pair->remote=0; - - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIGetDrawableInfo (register ClientPtr client) -{ - xXF86DRIGetDrawableInfoReply rep; - DrawablePtr drawable; - WindowPtr window=NULL; - EphyrWindowPair *pair=NULL; - int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0; - drm_clip_rect_t *clipRects=NULL; - drm_clip_rect_t *backClipRects=NULL; - REQUEST(xXF86DRIGetDrawableInfoReq); - REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq); - - EPHYR_LOG ("enter\n") ; - memset (&rep, 0, sizeof (rep)) ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success || !drawable) { - EPHYR_LOG_ERROR ("could not get drawable\n") ; - return rc; - } - - if (drawable->type != DRAWABLE_WINDOW) { - EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ; - return BadImplementation ; - } - window = (WindowPtr)drawable ; - memset (&pair, 0, sizeof (pair)) ; - if (!findWindowPairFromLocal (window, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ; - return BadMatch ; - } - EPHYR_LOG ("clip list of xephyr gl drawable:\n") ; - for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) { - EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n", - REGION_RECTS (&window->clipList)[i].x1, - REGION_RECTS (&window->clipList)[i].y1, - REGION_RECTS (&window->clipList)[i].x2, - REGION_RECTS (&window->clipList)[i].y2) ; - } - - if (!ephyrDRIGetDrawableInfo (stuff->screen, - pair->remote/*the drawable in hostx*/, - (unsigned int*)&rep.drawableTableIndex, - (unsigned int*)&rep.drawableTableStamp, - (int*)&X, - (int*)&Y, - (int*)&W, - (int*)&H, - (int*)&rep.numClipRects, - &clipRects, - &backX, - &backY, - (int*)&rep.numBackClipRects, - &backClipRects)) { - return BadValue; - } - EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n", - (int)rep.numClipRects, (int)rep.numBackClipRects) ; - - rep.drawableX = X; - rep.drawableY = Y; - rep.drawableWidth = W; - rep.drawableHeight = H; - rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - - SIZEOF(xGenericReply)); - - rep.backX = backX; - rep.backY = backY; - - - if (rep.numClipRects) { - if (clipRects) { - ScreenPtr pScreen = screenInfo.screens[stuff->screen]; - int i=0; - EPHYR_LOG ("clip list of host gl drawable:\n") ; - for (i = 0; i < rep.numClipRects; i++) { - clipRects[i].x1 = max (clipRects[i].x1, 0); - clipRects[i].y1 = max (clipRects[i].y1, 0); - clipRects[i].x2 = min (clipRects[i].x2, - pScreen->width + clipRects[i].x1) ; - clipRects[i].y2 = min (clipRects[i].y2, - pScreen->width + clipRects[i].y1) ; - - EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n", - clipRects[i].x1, clipRects[i].y1, - clipRects[i].x2, clipRects[i].y2) ; - } - } else { - rep.numClipRects = 0; - } - } else { - EPHYR_LOG ("got zero host gl drawable clipping rects\n") ; - } - rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects; - backClipRects = clipRects ; - rep.numBackClipRects = rep.numClipRects ; - if (rep.numBackClipRects) - rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects; - EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ; - EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ; - - rep.length = bytes_to_int32(rep.length); - - WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep); - - if (rep.numClipRects) { - WriteToClient(client, - sizeof(drm_clip_rect_t) * rep.numClipRects, - (char *)clipRects); - } - - if (rep.numBackClipRects) { - WriteToClient(client, - sizeof(drm_clip_rect_t) * rep.numBackClipRects, - (char *)backClipRects); - } - xfree(clipRects); - clipRects = NULL ; - - EPHYR_LOG ("leave\n") ; - - return (client->noClientException); -} - -static int -ProcXF86DRIGetDeviceInfo (register ClientPtr client) -{ - xXF86DRIGetDeviceInfoReply rep; - drm_handle_t hFrameBuffer; - void *pDevPrivate; - REQUEST(xXF86DRIGetDeviceInfoReq); - REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if (!ephyrDRIGetDeviceInfo (stuff->screen, - &hFrameBuffer, - (int*)&rep.framebufferOrigin, - (int*)&rep.framebufferSize, - (int*)&rep.framebufferStride, - (int*)&rep.devPrivateSize, - &pDevPrivate)) { - return BadValue; - } - - rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff); -#if defined(LONG64) && !defined(__linux__) - rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32); -#else - rep.hFrameBufferHigh = 0; -#endif - - rep.length = 0; - if (rep.devPrivateSize) { - rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) - - SIZEOF(xGenericReply) + - pad_to_int32(rep.devPrivateSize)); - } - - WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep); - if (rep.length) { - WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate); - } - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIDispatch (register ClientPtr client) -{ - REQUEST(xReq); - EPHYR_LOG ("enter\n") ; - - switch (stuff->data) - { - case X_XF86DRIQueryVersion: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIQueryVersion(client); - } - case X_XF86DRIQueryDirectRenderingCapable: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIQueryDirectRenderingCapable(client); - } - } - - if (!LocalClient(client)) - return DRIErrorBase + XF86DRIClientNotLocal; - - switch (stuff->data) - { - case X_XF86DRIOpenConnection: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIOpenConnection(client); - } - case X_XF86DRICloseConnection: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRICloseConnection(client); - } - case X_XF86DRIGetClientDriverName: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIGetClientDriverName(client); - } - case X_XF86DRICreateContext: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRICreateContext(client); - } - case X_XF86DRIDestroyContext: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIDestroyContext(client); - } - case X_XF86DRICreateDrawable: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRICreateDrawable(client); - } - case X_XF86DRIDestroyDrawable: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIDestroyDrawable(client); - } - case X_XF86DRIGetDrawableInfo: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIGetDrawableInfo(client); - } - case X_XF86DRIGetDeviceInfo: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIGetDeviceInfo(client); - } - case X_XF86DRIAuthConnection: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIAuthConnection(client); - } - /* {Open,Close}FullScreen are deprecated now */ - default: { - EPHYR_LOG ("leave\n") ; - return BadRequest; - } - } -} - -static int -SProcXF86DRIQueryVersion (register ClientPtr client) -{ - register int n; - REQUEST(xXF86DRIQueryVersionReq); - swaps(&stuff->length, n); - return ProcXF86DRIQueryVersion(client); -} - -static int -SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client) -{ - register int n; - REQUEST(xXF86DRIQueryDirectRenderingCapableReq); - swaps(&stuff->length, n); - swapl(&stuff->screen, n); - return ProcXF86DRIQueryDirectRenderingCapable(client); -} - -static int -SProcXF86DRIDispatch (register ClientPtr client) -{ - REQUEST(xReq); - - EPHYR_LOG ("enter\n") ; - /* - * Only local clients are allowed DRI access, but remote clients still need - * these requests to find out cleanly. - */ - switch (stuff->data) - { - case X_XF86DRIQueryVersion: { - EPHYR_LOG ("leave\n") ; - return SProcXF86DRIQueryVersion(client); - } - case X_XF86DRIQueryDirectRenderingCapable: { - EPHYR_LOG ("leave\n") ; - return SProcXF86DRIQueryDirectRenderingCapable(client); - } - default: { - EPHYR_LOG ("leave\n") ; - return DRIErrorBase + XF86DRIClientNotLocal; - } - } -} +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * This file is heavily copied from hw/xfree86/dri/xf86dri.c
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <string.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86driproto.h>
+#include "misc.h"
+#include "privates.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "hostx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "protocol-versions.h"
+
+typedef struct {
+ int foo;
+} EphyrDRIWindowPrivRec;
+typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr;
+
+typedef struct {
+ CreateWindowProcPtr CreateWindow ;
+ DestroyWindowProcPtr DestroyWindow ;
+ MoveWindowProcPtr MoveWindow ;
+ PositionWindowProcPtr PositionWindow ;
+ ClipNotifyProcPtr ClipNotify ;
+} EphyrDRIScreenPrivRec;
+typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
+
+static int DRIErrorBase;
+
+static DISPATCH_PROC(ProcXF86DRIQueryVersion);
+static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(ProcXF86DRIOpenConnection);
+static DISPATCH_PROC(ProcXF86DRICloseConnection);
+static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
+static DISPATCH_PROC(ProcXF86DRICreateContext);
+static DISPATCH_PROC(ProcXF86DRIDestroyContext);
+static DISPATCH_PROC(ProcXF86DRICreateDrawable);
+static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
+static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
+static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
+static DISPATCH_PROC(ProcXF86DRIDispatch);
+static DISPATCH_PROC(ProcXF86DRIAuthConnection);
+
+static DISPATCH_PROC(SProcXF86DRIQueryVersion);
+static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(SProcXF86DRIDispatch);
+
+static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ;
+static Bool ephyrDRICreateWindow (WindowPtr a_win) ;
+static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ;
+static void ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind);
+static Bool ephyrDRIPositionWindow (WindowPtr a_win,
+ int x, int y) ;
+static void ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y) ;
+
+static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ;
+static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
+static Bool findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair);
+
+static unsigned char DRIReqCode = 0;
+
+static int ephyrDRIWindowKeyIndex;
+static DevPrivateKey ephyrDRIWindowKey = &ephyrDRIWindowKeyIndex;
+static int ephyrDRIScreenKeyIndex;
+static DevPrivateKey ephyrDRIScreenKey = &ephyrDRIScreenKeyIndex;
+
+#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \
+ dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey))
+#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \
+ dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey))
+
+
+Bool
+ephyrDRIExtensionInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ ExtensionEntry* extEntry=NULL;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_has_dri ()) {
+ EPHYR_LOG ("host does not have DRI extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have DRI extension\n") ;
+ if (!hostx_has_xshape ()) {
+ EPHYR_LOG ("host does not have XShape extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have XShape extension\n") ;
+
+#ifdef XF86DRI_EVENTS
+ EventType = CreateNewResourceType (XF86DRIFreeEvents, "DRIEvents");
+ if (!EventType) {
+ EPHYR_LOG_ERROR ("failed to register DRI event resource type\n") ;
+ goto out ;
+ }
+#endif
+
+ if ((extEntry = AddExtension(XF86DRINAME,
+ XF86DRINumberEvents,
+ XF86DRINumberErrors,
+ ProcXF86DRIDispatch,
+ SProcXF86DRIDispatch,
+ NULL,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ } else {
+ EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
+ goto out ;
+ }
+ screen_priv = calloc(1, sizeof (EphyrDRIScreenPrivRec)) ;
+ if (!screen_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
+ goto out ;
+ }
+ dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv);
+
+ if (!ephyrDRIScreenInit (a_screen)) {
+ EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
+ goto out ;
+ }
+ EphyrMirrorHostVisuals (a_screen) ;
+ is_ok=TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIScreenInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ;
+
+ screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ;
+
+ screen_priv->CreateWindow = a_screen->CreateWindow ;
+ screen_priv->DestroyWindow = a_screen->DestroyWindow ;
+ screen_priv->MoveWindow = a_screen->MoveWindow ;
+ screen_priv->PositionWindow = a_screen->PositionWindow ;
+ screen_priv->ClipNotify = a_screen->ClipNotify ;
+
+ a_screen->CreateWindow = ephyrDRICreateWindow ;
+ a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
+ a_screen->MoveWindow = ephyrDRIMoveWindow ;
+ a_screen->PositionWindow = ephyrDRIPositionWindow ;
+ a_screen->ClipNotify = ephyrDRIClipNotify ;
+
+ is_ok = TRUE ;
+
+ return is_ok ;
+}
+
+static Bool
+ephyrDRICreateWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->CreateWindow,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. win:%p\n", a_win) ;
+
+ screen->CreateWindow = screen_priv->CreateWindow ;
+ is_ok = (*screen->CreateWindow) (a_win) ;
+ screen->CreateWindow = ephyrDRICreateWindow ;
+
+ if (is_ok) {
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ }
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIDestroyWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->DestroyWindow,
+ FALSE) ;
+
+ screen->DestroyWindow = screen_priv->DestroyWindow ;
+ if (screen->DestroyWindow) {
+ is_ok = (*screen->DestroyWindow) (a_win) ;
+ }
+ screen->DestroyWindow = ephyrDRIDestroyWindow ;
+
+ if (is_ok) {
+ EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (win_priv) {
+ destroyHostPeerWindow (a_win) ;
+ free(win_priv) ;
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ EPHYR_LOG ("destroyed the remote peer window\n") ;
+ }
+ }
+ return is_ok ;
+}
+
+static void
+ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+ int x=0,y=0;/*coords relative to parent window*/
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv
+ && screen_priv->MoveWindow) ;
+
+ screen->MoveWindow = screen_priv->MoveWindow ;
+ if (screen->MoveWindow) {
+ (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
+ }
+ screen->MoveWindow = ephyrDRIMoveWindow ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ if (!a_win->parent) {
+ EPHYR_LOG ("cannot move root window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*compute position relative to parent window*/
+ x = a_win->drawable.x - a_win->parent->drawable.x ;
+ y = a_win->drawable.y - a_win->parent->drawable.y ;
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = x ;
+ geo.y = y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+static Bool
+ephyrDRIPositionWindow (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->PositionWindow,
+ FALSE) ;
+
+ screen->PositionWindow = screen_priv->PositionWindow ;
+ if (screen->PositionWindow) {
+ (*screen->PositionWindow) (a_win, a_x, a_y) ;
+ }
+ screen->PositionWindow = ephyrDRIPositionWindow ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_x ;
+ geo.y = a_y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+ return is_ok ;
+}
+
+static void
+ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrRect *rects=NULL;
+ int i=0 ;
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ;
+
+ screen->ClipNotify = screen_priv->ClipNotify ;
+ if (screen->ClipNotify) {
+ (*screen->ClipNotify) (a_win, a_x, a_y) ;
+ }
+ screen->ClipNotify = ephyrDRIClipNotify ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ rects = calloc(REGION_NUM_RECTS (&a_win->clipList),
+ sizeof (EphyrRect)) ;
+ for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) {
+ memmove (&rects[i],
+ ®ION_RECTS (&a_win->clipList)[i],
+ sizeof (EphyrRect)) ;
+ rects[i].x1 -= a_win->drawable.x;
+ rects[i].x2 -= a_win->drawable.x;
+ rects[i].y1 -= a_win->drawable.y;
+ rects[i].y2 -= a_win->drawable.y;
+ }
+ /*
+ * push the clipping region of this window
+ * to the peer window in the host
+ */
+ is_ok = hostx_set_window_bounding_rectangles
+ (pair->remote,
+ rects,
+ REGION_NUM_RECTS (&a_win->clipList)) ;
+ is_ok = TRUE ;
+
+out:
+ free(rects) ;
+ rects = NULL ;
+
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+/**
+ * Duplicates a visual of a_screen
+ * In screen a_screen, for depth a_depth, find a visual which
+ * bitsPerRGBValue and colormap size equal
+ * a_bits_per_rgb_values and a_colormap_entries.
+ * The ID of that duplicated visual is set to a_new_id.
+ * That duplicated visual is then added to the list of visuals
+ * of the screen.
+ */
+static Bool
+EphyrDuplicateVisual (unsigned int a_screen,
+ short a_depth,
+ short a_class,
+ short a_bits_per_rgb_values,
+ short a_colormap_entries,
+ unsigned int a_red_mask,
+ unsigned int a_green_mask,
+ unsigned int a_blue_mask,
+ unsigned int a_new_id)
+{
+ Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
+ ScreenPtr screen=NULL ;
+ VisualRec new_visual, *new_visuals=NULL ;
+ int i=0 ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (a_screen > screenInfo.numScreens) {
+ EPHYR_LOG_ERROR ("bad screen number\n") ;
+ goto out;
+ }
+ memset (&new_visual, 0, sizeof (VisualRec)) ;
+
+ /*get the screen pointed to by a_screen*/
+ screen = screenInfo.screens[a_screen] ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+
+ /*
+ * In that screen, first look for an existing visual that has the
+ * same characteristics as those passed in parameter
+ * to this function and copy it.
+ */
+ for (i=0; i < screen->numVisuals; i++) {
+ if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
+ screen->visuals[i].ColormapEntries == a_colormap_entries ) {
+ /*copy the visual found*/
+ memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
+ new_visual.vid = a_new_id ;
+ new_visual.class = a_class ;
+ new_visual.redMask = a_red_mask ;
+ new_visual.greenMask = a_green_mask ;
+ new_visual.blueMask = a_blue_mask ;
+ found_visual = TRUE ;
+ EPHYR_LOG ("found a visual that matches visual id: %d\n",
+ a_new_id) ;
+ break;
+ }
+ }
+ if (!found_visual) {
+ EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
+ goto out ;
+ }
+ /*
+ * be prepare to extend screen->visuals to add new_visual to it
+ */
+ new_visuals = calloc(screen->numVisuals+1, sizeof (VisualRec)) ;
+ memmove (new_visuals,
+ screen->visuals,
+ screen->numVisuals*sizeof (VisualRec)) ;
+ memmove (&new_visuals[screen->numVisuals],
+ &new_visual,
+ sizeof (VisualRec)) ;
+ /*
+ * Now, in that same screen, update the screen->allowedDepths member.
+ * In that array, each element represents the visuals applicable to
+ * a given depth. So we need to add an entry matching the new visual
+ * that we are going to add to screen->visuals
+ */
+ for (i=0; i<screen->numDepths; i++) {
+ VisualID *vids=NULL;
+ DepthPtr cur_depth=NULL ;
+ /*find the entry matching a_depth*/
+ if (screen->allowedDepths[i].depth != a_depth)
+ continue ;
+ cur_depth = &screen->allowedDepths[i];
+ /*
+ * extend the list of visual IDs in that entry,
+ * so to add a_new_id in there.
+ */
+ vids = realloc(cur_depth->vids,
+ (cur_depth->numVids+1)*sizeof (VisualID));
+ if (!vids) {
+ EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
+ goto out ;
+ }
+ vids[cur_depth->numVids] = a_new_id ;
+ /*
+ * Okay now commit our change.
+ * Do really update screen->allowedDepths[i]
+ */
+ cur_depth->numVids++ ;
+ cur_depth->vids = vids ;
+ found_depth=TRUE;
+ }
+ if (!found_depth) {
+ EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
+ a_screen) ;
+ goto out ;
+ }
+ /*
+ * Commit our change to screen->visuals
+ */
+ free(screen->visuals) ;
+ screen->visuals = new_visuals ;
+ screen->numVisuals++ ;
+ new_visuals = NULL ;
+
+ is_ok = TRUE ;
+out:
+ free(new_visuals) ;
+ new_visuals = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+/**
+ * Duplicates the visuals of the host X server.
+ * This is necessary to have visuals that have the same
+ * ID as those of the host X. It is important to have that for
+ * GLX.
+ */
+static Bool
+EphyrMirrorHostVisuals (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE;
+ EphyrHostVisualInfo *visuals=NULL;
+ int nb_visuals=0, i=0;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
+ EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
+ goto out ;
+ }
+ for (i=0; i<nb_visuals; i++) {
+ if (!EphyrDuplicateVisual (a_screen->myNum,
+ visuals[i].depth,
+ visuals[i].class,
+ visuals[i].bits_per_rgb,
+ visuals[i].colormap_size,
+ visuals[i].red_mask,
+ visuals[i].green_mask,
+ visuals[i].blue_mask,
+ visuals[i].visualid)) {
+ EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
+ (int)visuals[i].visualid) ;
+ }
+ }
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+
+static int
+ProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ xXF86DRIQueryVersionReply rep;
+ register int n;
+ REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+
+ EPHYR_LOG ("enter\n") ;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
+ rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
+ rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swapl(&rep.patchVersion, n);
+ }
+ WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ Bool isCapable;
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
+ return BadValue;
+ }
+ rep.isCapable = isCapable;
+
+ if (!LocalClient(client) || client->swapped)
+ rep.isCapable = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+
+ return Success;
+}
+
+static int
+ProcXF86DRIOpenConnection (register ClientPtr client)
+{
+ xXF86DRIOpenConnectionReply rep;
+ drm_handle_t hSAREA;
+ char* busIdString;
+ REQUEST(xXF86DRIOpenConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIOpenConnection(stuff->screen,
+ &hSAREA,
+ &busIdString)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.busIdStringLength = 0;
+ if (busIdString)
+ rep.busIdStringLength = strlen(busIdString);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+ pad_to_int32(rep.busIdStringLength));
+
+ rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
+#else
+ rep.hSAREAHigh = 0;
+#endif
+
+ WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
+ if (rep.busIdStringLength)
+ WriteToClient(client, rep.busIdStringLength, busIdString);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIAuthConnection (register ClientPtr client)
+{
+ xXF86DRIAuthConnectionReply rep;
+ REQUEST(xXF86DRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.authenticated = 1;
+
+ if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
+ ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
+ rep.authenticated = 0;
+ }
+ WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRICloseConnection (register ClientPtr client)
+{
+ REQUEST(xXF86DRICloseConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ /*
+ DRICloseConnection( screenInfo.screens[stuff->screen]);
+ */
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIGetClientDriverName (register ClientPtr client)
+{
+ xXF86DRIGetClientDriverNameReply rep;
+ char* clientDriverName;
+ REQUEST(xXF86DRIGetClientDriverNameReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ ephyrDRIGetClientDriverName (stuff->screen,
+ (int *)&rep.ddxDriverMajorVersion,
+ (int *)&rep.ddxDriverMinorVersion,
+ (int *)&rep.ddxDriverPatchVersion,
+ &clientDriverName);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.clientDriverNameLength = 0;
+ if (clientDriverName)
+ rep.clientDriverNameLength = strlen(clientDriverName);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.clientDriverNameLength));
+
+ WriteToClient(client,
+ sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
+ if (rep.clientDriverNameLength)
+ WriteToClient(client,
+ rep.clientDriverNameLength,
+ clientDriverName);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRICreateContext (register ClientPtr client)
+{
+ xXF86DRICreateContextReply rep;
+ ScreenPtr pScreen;
+ VisualPtr visual;
+ int i=0;
+ unsigned long context_id=0;
+ REQUEST(xXF86DRICreateContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ pScreen = screenInfo.screens[stuff->screen];
+ visual = pScreen->visuals;
+
+ /* Find the requested X visual */
+ for (i = 0; i < pScreen->numVisuals; i++, visual++)
+ if (visual->vid == stuff->visual)
+ break;
+ if (i == pScreen->numVisuals) {
+ /* No visual found */
+ return BadValue;
+ }
+
+ context_id = stuff->context ;
+ if (!ephyrDRICreateContext (stuff->screen,
+ stuff->visual,
+ &context_id,
+ (drm_context_t *)&rep.hHWContext)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyContext (register ClientPtr client)
+{
+ REQUEST(xXF86DRIDestroyContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ EPHYR_LOG ("enter\n") ;
+
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) {
+ return BadValue;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static Bool
+getWindowVisual (const WindowPtr a_win,
+ VisualPtr *a_visual)
+{
+ int i=0, visual_id=0 ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win
+ && a_win->drawable.pScreen
+ && a_win->drawable.pScreen->visuals,
+ FALSE) ;
+
+ visual_id = wVisual (a_win) ;
+ for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) {
+ if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
+ *a_visual = &a_win->drawable.pScreen->visuals[i] ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+
+#define NUM_WINDOW_PAIRS 256
+static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ;
+
+static Bool
+appendWindowPairToList (WindowPtr a_local,
+ int a_remote)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ;
+
+ EPHYR_LOG ("(local,remote):(%p, %d)\n", a_local, a_remote) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == NULL) {
+ window_pairs[i].local = a_local ;
+ window_pairs[i].remote = a_remote ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == a_local) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+Bool
+findWindowPairFromRemote (int a_remote,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].remote == a_remote) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+createHostPeerWindow (const WindowPtr a_win,
+ int *a_peer_win)
+{
+ Bool is_ok=FALSE ;
+ VisualPtr visual=NULL;
+ EphyrBox geo ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. a_win '%p'\n", a_win) ;
+ if (!getWindowVisual (a_win, &visual)) {
+ EPHYR_LOG_ERROR ("failed to get window visual\n") ;
+ goto out ;
+ }
+ if (!visual) {
+ EPHYR_LOG_ERROR ("failed to create visual\n") ;
+ goto out ;
+ }
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_win->drawable.x ;
+ geo.y = a_win->drawable.y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ if (!hostx_create_window (a_win->drawable.pScreen->myNum,
+ &geo, visual->vid, a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ goto out ;
+ }
+ if (!appendWindowPairToList (a_win, *a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to append window to pair list\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ;
+ return is_ok ;
+}
+
+static Bool
+destroyHostPeerWindow (const WindowPtr a_win)
+{
+ Bool is_ok = FALSE ;
+ EphyrWindowPair *pair=NULL ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find peer to local window\n") ;
+ goto out;
+ }
+ hostx_destroy_window (pair->remote) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+static int
+ProcXF86DRICreateDrawable (ClientPtr client)
+{
+ xXF86DRICreateDrawableReply rep;
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrDRIWindowPrivPtr win_priv=NULL;
+ int rc=0, remote_win=0;
+ REQUEST(xXF86DRICreateDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ EPHYR_LOG ("lookedup drawable %p\n", drawable) ;
+ window = (WindowPtr)drawable;
+ if (findWindowPairFromLocal (window, &pair) && pair) {
+ remote_win = pair->remote ;
+ EPHYR_LOG ("found window '%p' paire with remote '%d'\n",
+ window, remote_win) ;
+ } else if (!createHostPeerWindow (window, &remote_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ return BadAlloc ;
+ }
+
+ if (!ephyrDRICreateDrawable (stuff->screen,
+ remote_win,
+ (drm_drawable_t *)&rep.hHWDrawable)) {
+ EPHYR_LOG_ERROR ("failed to create dri drawable\n") ;
+ return BadValue;
+ }
+
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ;
+ if (!win_priv) {
+ win_priv = calloc(1, sizeof (EphyrDRIWindowPrivRec)) ;
+ if (!win_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate window private\n") ;
+ return BadAlloc ;
+ }
+ dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv);
+ EPHYR_LOG ("paired window '%p' with remote '%d'\n",
+ window, remote_win) ;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyDrawable (register ClientPtr client)
+{
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ int rc=0;
+ REQUEST(xXF86DRIDestroyDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rc = dixLookupDrawable(&drawable,
+ stuff->drawable,
+ client,
+ 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable;
+ if (!findWindowPairFromLocal (window, &pair) && pair) {
+ EPHYR_LOG_ERROR ("failed to find pair window\n") ;
+ return BadImplementation;
+ }
+ if (!ephyrDRIDestroyDrawable(stuff->screen,
+ pair->remote/*drawable in host x*/)) {
+ EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ;
+ return BadImplementation;
+ }
+ pair->local=NULL ;
+ pair->remote=0;
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDrawableInfo (register ClientPtr client)
+{
+ xXF86DRIGetDrawableInfoReply rep;
+ DrawablePtr drawable;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
+ drm_clip_rect_t *clipRects=NULL;
+ drm_clip_rect_t *backClipRects=NULL;
+ REQUEST(xXF86DRIGetDrawableInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+
+ EPHYR_LOG ("enter\n") ;
+ memset (&rep, 0, sizeof (rep)) ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success || !drawable) {
+ EPHYR_LOG_ERROR ("could not get drawable\n") ;
+ return rc;
+ }
+
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable ;
+ memset (&pair, 0, sizeof (pair)) ;
+ if (!findWindowPairFromLocal (window, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
+ return BadMatch ;
+ }
+ EPHYR_LOG ("clip list of xephyr gl drawable:\n") ;
+ for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) {
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ REGION_RECTS (&window->clipList)[i].x1,
+ REGION_RECTS (&window->clipList)[i].y1,
+ REGION_RECTS (&window->clipList)[i].x2,
+ REGION_RECTS (&window->clipList)[i].y2) ;
+ }
+
+ if (!ephyrDRIGetDrawableInfo (stuff->screen,
+ pair->remote/*the drawable in hostx*/,
+ (unsigned int*)&rep.drawableTableIndex,
+ (unsigned int*)&rep.drawableTableStamp,
+ (int*)&X,
+ (int*)&Y,
+ (int*)&W,
+ (int*)&H,
+ (int*)&rep.numClipRects,
+ &clipRects,
+ &backX,
+ &backY,
+ (int*)&rep.numBackClipRects,
+ &backClipRects)) {
+ return BadValue;
+ }
+ EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
+ (int)rep.numClipRects, (int)rep.numBackClipRects) ;
+
+ rep.drawableX = X;
+ rep.drawableY = Y;
+ rep.drawableWidth = W;
+ rep.drawableHeight = H;
+ rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply));
+
+ rep.backX = backX;
+ rep.backY = backY;
+
+
+ if (rep.numClipRects) {
+ if (clipRects) {
+ ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+ int i=0;
+ EPHYR_LOG ("clip list of host gl drawable:\n") ;
+ for (i = 0; i < rep.numClipRects; i++) {
+ clipRects[i].x1 = max (clipRects[i].x1, 0);
+ clipRects[i].y1 = max (clipRects[i].y1, 0);
+ clipRects[i].x2 = min (clipRects[i].x2,
+ pScreen->width + clipRects[i].x1) ;
+ clipRects[i].y2 = min (clipRects[i].y2,
+ pScreen->width + clipRects[i].y1) ;
+
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ clipRects[i].x1, clipRects[i].y1,
+ clipRects[i].x2, clipRects[i].y2) ;
+ }
+ } else {
+ rep.numClipRects = 0;
+ }
+ } else {
+ EPHYR_LOG ("got zero host gl drawable clipping rects\n") ;
+ }
+ rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+ backClipRects = clipRects ;
+ rep.numBackClipRects = rep.numClipRects ;
+ if (rep.numBackClipRects)
+ rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
+ EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
+ EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ;
+
+ rep.length = bytes_to_int32(rep.length);
+
+ WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
+
+ if (rep.numClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numClipRects,
+ (char *)clipRects);
+ }
+
+ if (rep.numBackClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+ (char *)backClipRects);
+ }
+ free(clipRects);
+ clipRects = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDeviceInfo (register ClientPtr client)
+{
+ xXF86DRIGetDeviceInfoReply rep;
+ drm_handle_t hFrameBuffer;
+ void *pDevPrivate;
+ REQUEST(xXF86DRIGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIGetDeviceInfo (stuff->screen,
+ &hFrameBuffer,
+ (int*)&rep.framebufferOrigin,
+ (int*)&rep.framebufferSize,
+ (int*)&rep.framebufferStride,
+ (int*)&rep.devPrivateSize,
+ &pDevPrivate)) {
+ return BadValue;
+ }
+
+ rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
+#else
+ rep.hFrameBufferHigh = 0;
+#endif
+
+ rep.length = 0;
+ if (rep.devPrivateSize) {
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.devPrivateSize));
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
+ if (rep.length) {
+ WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
+ }
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+ EPHYR_LOG ("enter\n") ;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ }
+
+ if (!LocalClient(client))
+ return DRIErrorBase + XF86DRIClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIOpenConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIOpenConnection(client);
+ }
+ case X_XF86DRICloseConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICloseConnection(client);
+ }
+ case X_XF86DRIGetClientDriverName: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetClientDriverName(client);
+ }
+ case X_XF86DRICreateContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateContext(client);
+ }
+ case X_XF86DRIDestroyContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyContext(client);
+ }
+ case X_XF86DRICreateDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateDrawable(client);
+ }
+ case X_XF86DRIDestroyDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyDrawable(client);
+ }
+ case X_XF86DRIGetDrawableInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDrawableInfo(client);
+ }
+ case X_XF86DRIGetDeviceInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDeviceInfo(client);
+ }
+ case X_XF86DRIAuthConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIAuthConnection(client);
+ }
+ /* {Open,Close}FullScreen are deprecated now */
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return BadRequest;
+ }
+ }
+}
+
+static int
+SProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXF86DRIQueryVersion(client);
+}
+
+static int
+SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->screen, n);
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+
+ EPHYR_LOG ("enter\n") ;
+ /*
+ * Only local clients are allowed DRI access, but remote clients still need
+ * these requests to find out cleanly.
+ */
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return DRIErrorBase + XF86DRIClientNotLocal;
+ }
+ }
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrglxext.c b/xorg-server/hw/kdrive/ephyr/ephyrglxext.c index a0278cc2b..d6b8ca66d 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrglxext.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrglxext.c @@ -1,723 +1,723 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@openedhand.com> - * - * Copyright © 2007 OpenedHand Ltd - * - * 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, and that the name of OpenedHand Ltd not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. OpenedHand Ltd makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - * Authors: - * Dodji Seketeli <dodji@openedhand.com> - */ -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif - -#include "extnsionst.h" -#include "ephyrglxext.h" -#include "ephyrhostglx.h" -#define _HAVE_XALLOC_DECLS -#include "ephyrlog.h" -#include <GL/glxproto.h> -#include "glx/glxserver.h" -#include "glx/indirect_table.h" -#include "glx/indirect_util.h" -#include "glx/unpack.h" -#include "hostx.h" - - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - - -int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ; -int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ; -int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ; -int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ; -int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ; -int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ; -int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc); -int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc); -int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc); -int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc); -int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ; -int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; - -Bool -ephyrHijackGLXExtension (void) -{ - const void *(*dispatch_functions)[2]; - - if (!hostx_has_glx ()) { - EPHYR_LOG ("host X does not have GLX\n") ; - return FALSE ; - } - EPHYR_LOG ("host X does have GLX\n") ; - - if (!Single_dispatch_info.dispatch_functions) { - EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ; - return FALSE ; - } - /* - * hijack some single entry point dispatch functions - */ - dispatch_functions = Single_dispatch_info.dispatch_functions ; - EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ; - - dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ; - dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ; - - dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ; - dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ; - dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ; - dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ; - - dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ; - dispatch_functions[X_GLXQueryServerString][1] = - ephyrGLXQueryServerStringSwap ; - - dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ; - dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ; - - dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ; - dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ; - - dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ; - dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ; - - dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ; - dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ; - - dispatch_functions[73][0] = ephyrGLXGetString ; - dispatch_functions[73][1] = ephyrGLXGetStringSwap ; - - dispatch_functions[61][0] = ephyrGLXGetIntegerv ; - dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ; - - /* - * hijack some vendor priv entry point dispatch functions - */ - dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ; - dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX; - dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap; - EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ; - - return TRUE ; -} - -/********************* - * implementation of - * hijacked GLX entry - * points - ********************/ - -int -ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc) -{ - ClientPtr client = a_cl->client; - xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc; - xGLXQueryVersionReply reply; - int major, minor; - int res = BadImplementation ; - - EPHYR_LOG ("enter\n") ; - - major = req->majorVersion ; - minor = req->minorVersion ; - - if (!ephyrHostGLXQueryVersion (&major, &minor)) { - EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ; - goto out ; - } - EPHYR_LOG ("major:%d, minor:%d\n", - major, minor); - reply.majorVersion = major ; - reply.minorVersion = minor ; - reply.length = 0 ; - reply.type = X_Reply ; - reply.sequenceNumber = client->sequence ; - - if (client->swapped) { - __glXSwapQueryVersionReply(client, &reply); - } else { - WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); - } - - res = Success ; -out: - EPHYR_LOG ("leave\n") ; - return res; -} - -int -ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc; - __GLX_DECLARE_SWAP_VARIABLES; - - __GLX_SWAP_SHORT (&req->length); - __GLX_SWAP_INT (&req->majorVersion); - __GLX_SWAP_INT (&req->minorVersion); - return ephyrGLXQueryVersion (a_cl, a_pc) ; -} - -static int -ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl, - GLbyte *a_pc, - Bool a_do_swap) -{ - xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc; - ClientPtr client = a_cl->client; - xGLXGetVisualConfigsReply reply; - int32_t *props_buf=NULL, num_visuals=0, - num_props=0, res=BadImplementation, i=0, - props_per_visual_size=0, - props_buf_size=0; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - EPHYR_LOG ("enter\n") ; - - if (!ephyrHostGLXGetVisualConfigs (req->screen, - &num_visuals, - &num_props, - &props_buf_size, - &props_buf)) { - EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ; - goto out ; - } - EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ; - - reply.numVisuals = num_visuals; - reply.numProps = num_props; - reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (a_do_swap) { - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.numVisuals); - __GLX_SWAP_INT(&reply.numProps); - __GLX_SWAP_INT_ARRAY (props_buf, num_props) ; - } - WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply); - props_per_visual_size = props_buf_size/num_visuals ; - for (i=0; i < num_visuals; i++) { - WriteToClient (client, - props_per_visual_size, - (char*)props_buf +i*props_per_visual_size); - } - res = Success ; - -out: - EPHYR_LOG ("leave\n") ; - xfree (props_buf) ; - props_buf = NULL ; - - return res ; -} - -static int -ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl, - GLbyte *a_pc, - Bool a_do_swap) -{ - xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc; - ClientPtr client = a_cl->client; - xGLXGetVisualConfigsReply reply; - int32_t *props_buf=NULL, num_visuals=0, - num_props=0, res=BadImplementation, i=0, - props_per_visual_size=0, - props_buf_size=0; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - EPHYR_LOG ("enter\n") ; - - if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen, - &num_visuals, - &num_props, - &props_buf_size, - &props_buf)) { - EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ; - goto out ; - } - EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ; - - reply.numVisuals = num_visuals; - reply.numProps = num_props; - reply.length = props_buf_size >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (a_do_swap) { - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.numVisuals); - __GLX_SWAP_INT(&reply.numProps); - __GLX_SWAP_INT_ARRAY (props_buf, num_props) ; - } - WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply); - props_per_visual_size = props_buf_size/num_visuals ; - for (i=0; i < num_visuals; i++) { - WriteToClient (client, - props_per_visual_size, - &((char*)props_buf)[i*props_per_visual_size]); - } - res = Success ; - -out: - EPHYR_LOG ("leave\n") ; - xfree (props_buf) ; - props_buf = NULL ; - - return res ; -} - -int -ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ; -} - -int -ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ; -} - - -int -ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc) -{ - int res=BadImplementation ; - xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc; - - EPHYR_LOG ("enter\n") ; - if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) { - EPHYR_LOG_ERROR ("failed to send client info to host\n") ; - goto out ; - } - res = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -int -ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc; - __GLX_DECLARE_SWAP_VARIABLES; - - __GLX_SWAP_SHORT (&req->length); - __GLX_SWAP_INT (&req->major); - __GLX_SWAP_INT (&req->minor); - __GLX_SWAP_INT (&req->numbytes); - - return ephyrGLXClientInfo (a_cl, a_pc) ; -} - -int -ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) -{ - int res = BadImplementation ; - ClientPtr client = a_cl->client; - xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc; - xGLXQueryServerStringReply reply; - char *server_string=NULL, *buf=NULL; - int length=0 ; - - EPHYR_LOG ("enter\n") ; - if (!ephyrHostGLXGetStringFromServer (req->screen, - req->name, - EPHYR_HOST_GLX_QueryServerString, - &server_string)) { - EPHYR_LOG_ERROR ("failed to query string from host\n") ; - goto out ; - } - EPHYR_LOG ("string: %s\n", server_string) ; - length= strlen (server_string) + 1; - reply.type = X_Reply ; - reply.sequenceNumber = client->sequence ; - reply.length = __GLX_PAD (length) >> 2 ; - reply.n = length ; - buf = xcalloc (reply.length << 2, 1); - if (!buf) { - EPHYR_LOG_ERROR ("failed to allocate string\n;"); - return BadAlloc; - } - memcpy (buf, server_string, length); - - WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply); - WriteToClient(client, (int)(reply.length << 2), server_string); - - res = Success ; - -out: - EPHYR_LOG ("leave\n") ; - xfree (server_string) ; - server_string = NULL; - - xfree (buf); - buf = NULL; - - return res ; -} - -int -ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) -{ - EPHYR_LOG_ERROR ("not yet implemented\n") ; - return BadImplementation ; -} - - -int -ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ; -} - -int -ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ; -} - -static int -ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap) -{ - int res=BadImplementation; - EphyrHostWindowAttributes host_w_attrs ; - __GLX_DECLARE_SWAP_VARIABLES; - - EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ; - EPHYR_LOG ("enter\n") ; - - if (a_do_swap) { - __GLX_SWAP_SHORT(&a_req->length); - __GLX_SWAP_INT(&a_req->context); - __GLX_SWAP_INT(&a_req->visual); - __GLX_SWAP_INT(&a_req->screen); - __GLX_SWAP_INT(&a_req->shareList); - } - - EPHYR_LOG ("context creation requested. localid:%d, " - "screen:%d, visual:%d, direct:%d\n", - (int)a_req->context, (int)a_req->screen, - (int)a_req->visual, (int)a_req->isDirect) ; - - memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ; - if (!hostx_get_window_attributes (hostx_get_window (a_req->screen), - &host_w_attrs)) { - EPHYR_LOG_ERROR ("failed to get host window attrs\n") ; - goto out ; - } - - EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ; - - if (!ephyrHostGLXCreateContext (a_req->screen, - host_w_attrs.visualid, - a_req->context, - a_req->shareList, - a_req->isDirect)) { - EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ; - goto out ; - } - res = Success; -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -int -ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - - return ephyrGLXCreateContextReal (req, FALSE) ; -} - -int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - return ephyrGLXCreateContextReal (req, TRUE) ; -} - -static int -ephyrGLXDestroyContextReal (__GLXclientState *a_cl, - GLbyte *a_pc, - Bool a_do_swap) -{ - int res=BadImplementation; - ClientPtr client = a_cl->client; - xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc; - - EPHYR_LOG ("enter. id:%d\n", (int)req->context) ; - if (!ephyrHostDestroyContext (req->context)) { - EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ; - client->errorValue = req->context ; - goto out ; - } - res = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -int -ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ; -} - -int -ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ; -} - -static int -ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) -{ - int res=BadImplementation; - xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc; - xGLXMakeCurrentReply reply ; - DrawablePtr drawable=NULL; - int rc=0; - - EPHYR_LOG ("enter\n") ; - rc = dixLookupDrawable (&drawable, - req->drawable, - a_cl->client, - 0, - DixReadAccess); - EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ; - EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ; - EPHYR_LOG ("screen nummber requested:%d\n", - drawable->pScreen->myNum) ; - - memset (&reply, 0, sizeof (reply)) ; - if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum), - req->context, - req->oldContextTag, - (int*)&reply.contextTag)) { - EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ; - goto out; - } - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = a_cl->client->sequence; - if (a_do_swap) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.contextTag); - } - WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply); - - res = Success ; -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -int -ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ; -} - -int -ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ; -} - -static int -ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) -{ - ClientPtr client=NULL ; - int context_tag=0, name=0, res=BadImplementation, length=0 ; - char *string=NULL; - __GLX_DECLARE_SWAP_VARIABLES; - - EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ; - - EPHYR_LOG ("enter\n") ; - - client = a_cl->client ; - - if (a_do_swap) { - __GLX_SWAP_INT (a_pc + 4); - __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE); - } - context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ; - a_pc += __GLX_SINGLE_HDR_SIZE; - name = *(GLenum*)(a_pc + 0); - EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ; - if (!ephyrHostGLXGetStringFromServer (context_tag, - name, - EPHYR_HOST_GLX_GetString, - &string)) { - EPHYR_LOG_ERROR ("failed to get string from server\n") ; - goto out ; - } - if (string) { - length = strlen (string) + 1; - EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ; - } else { - EPHYR_LOG ("got string: string (null)\n") ; - } - __GLX_BEGIN_REPLY (length); - __GLX_PUT_SIZE (length); - __GLX_SEND_HEADER (); - if (a_do_swap) { - __GLX_SWAP_REPLY_SIZE (); - __GLX_SWAP_REPLY_HEADER (); - } - WriteToClient (client, length, (char *)string); - - res = Success ; -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -int -ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ; -} - -int -ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ; -} - -static int -ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) -{ - int res=BadImplementation; - xGLXSingleReq * const req = (xGLXSingleReq *) a_pc; - GLenum int_name ; - int value=0 ; - GLint answer_buf_room[200]; - GLint *buf=NULL ; - - EPHYR_LOG ("enter\n") ; - - a_pc += __GLX_SINGLE_HDR_SIZE; - - int_name = *(GLenum*) (a_pc+0) ; - if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) { - EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ; - goto out ; - } - buf = __glXGetAnswerBuffer (a_cl, sizeof (value), - answer_buf_room, - sizeof (answer_buf_room), - 4) ; - - if (!buf) { - EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ; - res = BadAlloc ; - goto out ; - } - __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ; - res = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -int -ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ; -} - -int -ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ; -} - -static int -ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) -{ - int res=BadImplementation; - ClientPtr client = a_cl->client; - xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc; - xGLXIsDirectReply reply; - int is_direct=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - memset (&reply, 0, sizeof (reply)) ; - if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) { - EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ; - goto out ; - } - reply.isDirect = is_direct ; - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); - res = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -int -ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ; -} - -int -ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) -{ - return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ; -} +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "extnsionst.h"
+#include "ephyrglxext.h"
+#include "ephyrhostglx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include <GL/glxproto.h>
+#include "glx/glxserver.h"
+#include "glx/indirect_table.h"
+#include "glx/indirect_util.h"
+#include "glx/unpack.h"
+#include "hostx.h"
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+
+Bool
+ephyrHijackGLXExtension (void)
+{
+ const void *(*dispatch_functions)[2];
+
+ if (!hostx_has_glx ()) {
+ EPHYR_LOG ("host X does not have GLX\n") ;
+ return FALSE ;
+ }
+ EPHYR_LOG ("host X does have GLX\n") ;
+
+ if (!Single_dispatch_info.dispatch_functions) {
+ EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
+ return FALSE ;
+ }
+ /*
+ * hijack some single entry point dispatch functions
+ */
+ dispatch_functions = Single_dispatch_info.dispatch_functions ;
+ EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
+
+ dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
+ dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
+
+ dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
+ dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
+ dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
+ dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
+
+ dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
+ dispatch_functions[X_GLXQueryServerString][1] =
+ ephyrGLXQueryServerStringSwap ;
+
+ dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ;
+ dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ;
+
+ dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ;
+ dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ;
+
+ dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ;
+ dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ;
+
+ dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ;
+ dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ;
+
+ dispatch_functions[73][0] = ephyrGLXGetString ;
+ dispatch_functions[73][1] = ephyrGLXGetStringSwap ;
+
+ dispatch_functions[61][0] = ephyrGLXGetIntegerv ;
+ dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ;
+
+ /*
+ * hijack some vendor priv entry point dispatch functions
+ */
+ dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ;
+ dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
+ dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
+ EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ;
+
+ return TRUE ;
+}
+
+/*********************
+ * implementation of
+ * hijacked GLX entry
+ * points
+ ********************/
+
+int
+ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ ClientPtr client = a_cl->client;
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+ xGLXQueryVersionReply reply;
+ int major, minor;
+ int res = BadImplementation ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ major = req->majorVersion ;
+ minor = req->minorVersion ;
+
+ if (!ephyrHostGLXQueryVersion (&major, &minor)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("major:%d, minor:%d\n",
+ major, minor);
+ reply.majorVersion = major ;
+ reply.minorVersion = minor ;
+ reply.length = 0 ;
+ reply.type = X_Reply ;
+ reply.sequenceNumber = client->sequence ;
+
+ if (client->swapped) {
+ __glXSwapQueryVersionReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res;
+}
+
+int
+ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT (&req->length);
+ __GLX_SWAP_INT (&req->majorVersion);
+ __GLX_SWAP_INT (&req->minorVersion);
+ return ephyrGLXQueryVersion (a_cl, a_pc) ;
+}
+
+static int
+ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
+ ClientPtr client = a_cl->client;
+ xGLXGetVisualConfigsReply reply;
+ int32_t *props_buf=NULL, num_visuals=0,
+ num_props=0, res=BadImplementation, i=0,
+ props_per_visual_size=0,
+ props_buf_size=0;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXGetVisualConfigs (req->screen,
+ &num_visuals,
+ &num_props,
+ &props_buf_size,
+ &props_buf)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+ reply.numVisuals = num_visuals;
+ reply.numProps = num_props;
+ reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+ }
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+ props_per_visual_size = props_buf_size/num_visuals ;
+ for (i=0; i < num_visuals; i++) {
+ WriteToClient (client,
+ props_per_visual_size,
+ (char*)props_buf +i*props_per_visual_size);
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ free(props_buf) ;
+ props_buf = NULL ;
+
+ return res ;
+}
+
+static int
+ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc;
+ ClientPtr client = a_cl->client;
+ xGLXGetVisualConfigsReply reply;
+ int32_t *props_buf=NULL, num_visuals=0,
+ num_props=0, res=BadImplementation, i=0,
+ props_per_visual_size=0,
+ props_buf_size=0;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen,
+ &num_visuals,
+ &num_props,
+ &props_buf_size,
+ &props_buf)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+ reply.numVisuals = num_visuals;
+ reply.numProps = num_props;
+ reply.length = props_buf_size >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+ }
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+ props_per_visual_size = props_buf_size/num_visuals ;
+ for (i=0; i < num_visuals; i++) {
+ WriteToClient (client,
+ props_per_visual_size,
+ &((char*)props_buf)[i*props_per_visual_size]);
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ free(props_buf) ;
+ props_buf = NULL ;
+
+ return res ;
+}
+
+int
+ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
+}
+
+
+int
+ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ int res=BadImplementation ;
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
+ EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
+ goto out ;
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT (&req->length);
+ __GLX_SWAP_INT (&req->major);
+ __GLX_SWAP_INT (&req->minor);
+ __GLX_SWAP_INT (&req->numbytes);
+
+ return ephyrGLXClientInfo (a_cl, a_pc) ;
+}
+
+int
+ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ int res = BadImplementation ;
+ ClientPtr client = a_cl->client;
+ xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
+ xGLXQueryServerStringReply reply;
+ char *server_string=NULL, *buf=NULL;
+ int length=0 ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXGetStringFromServer (req->screen,
+ req->name,
+ EPHYR_HOST_GLX_QueryServerString,
+ &server_string)) {
+ EPHYR_LOG_ERROR ("failed to query string from host\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("string: %s\n", server_string) ;
+ length= strlen (server_string) + 1;
+ reply.type = X_Reply ;
+ reply.sequenceNumber = client->sequence ;
+ reply.length = __GLX_PAD (length) >> 2 ;
+ reply.n = length ;
+ buf = calloc(reply.length << 2, 1);
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to allocate string\n;");
+ return BadAlloc;
+ }
+ memcpy (buf, server_string, length);
+
+ WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
+ WriteToClient(client, (int)(reply.length << 2), server_string);
+
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ free(server_string) ;
+ server_string = NULL;
+
+ free(buf);
+ buf = NULL;
+
+ return res ;
+}
+
+int
+ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ EPHYR_LOG_ERROR ("not yet implemented\n") ;
+ return BadImplementation ;
+}
+
+
+int
+ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ EphyrHostWindowAttributes host_w_attrs ;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ;
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&a_req->length);
+ __GLX_SWAP_INT(&a_req->context);
+ __GLX_SWAP_INT(&a_req->visual);
+ __GLX_SWAP_INT(&a_req->screen);
+ __GLX_SWAP_INT(&a_req->shareList);
+ }
+
+ EPHYR_LOG ("context creation requested. localid:%d, "
+ "screen:%d, visual:%d, direct:%d\n",
+ (int)a_req->context, (int)a_req->screen,
+ (int)a_req->visual, (int)a_req->isDirect) ;
+
+ memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
+ if (!hostx_get_window_attributes (hostx_get_window (a_req->screen),
+ &host_w_attrs)) {
+ EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
+ goto out ;
+ }
+
+ EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ;
+
+ if (!ephyrHostGLXCreateContext (a_req->screen,
+ host_w_attrs.visualid,
+ a_req->context,
+ a_req->shareList,
+ a_req->isDirect)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ;
+ goto out ;
+ }
+ res = Success;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+
+ return ephyrGLXCreateContextReal (req, FALSE) ;
+}
+
+int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+ return ephyrGLXCreateContextReal (req, TRUE) ;
+}
+
+static int
+ephyrGLXDestroyContextReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ int res=BadImplementation;
+ ClientPtr client = a_cl->client;
+ xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
+
+ EPHYR_LOG ("enter. id:%d\n", (int)req->context) ;
+ if (!ephyrHostDestroyContext (req->context)) {
+ EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ;
+ client->errorValue = req->context ;
+ goto out ;
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
+ xGLXMakeCurrentReply reply ;
+ DrawablePtr drawable=NULL;
+ int rc=0;
+
+ EPHYR_LOG ("enter\n") ;
+ rc = dixLookupDrawable (&drawable,
+ req->drawable,
+ a_cl->client,
+ 0,
+ DixReadAccess);
+ EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
+ EPHYR_LOG ("screen nummber requested:%d\n",
+ drawable->pScreen->myNum) ;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
+ req->context,
+ req->oldContextTag,
+ (int*)&reply.contextTag)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
+ goto out;
+ }
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = a_cl->client->sequence;
+ if (a_do_swap) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.contextTag);
+ }
+ WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ ClientPtr client=NULL ;
+ int context_tag=0, name=0, res=BadImplementation, length=0 ;
+ char *string=NULL;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ client = a_cl->client ;
+
+ if (a_do_swap) {
+ __GLX_SWAP_INT (a_pc + 4);
+ __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE);
+ }
+ context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ;
+ a_pc += __GLX_SINGLE_HDR_SIZE;
+ name = *(GLenum*)(a_pc + 0);
+ EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ;
+ if (!ephyrHostGLXGetStringFromServer (context_tag,
+ name,
+ EPHYR_HOST_GLX_GetString,
+ &string)) {
+ EPHYR_LOG_ERROR ("failed to get string from server\n") ;
+ goto out ;
+ }
+ if (string) {
+ length = strlen (string) + 1;
+ EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ;
+ } else {
+ EPHYR_LOG ("got string: string (null)\n") ;
+ }
+ __GLX_BEGIN_REPLY (length);
+ __GLX_PUT_SIZE (length);
+ __GLX_SEND_HEADER ();
+ if (a_do_swap) {
+ __GLX_SWAP_REPLY_SIZE ();
+ __GLX_SWAP_REPLY_HEADER ();
+ }
+ WriteToClient (client, length, (char *)string);
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ xGLXSingleReq * const req = (xGLXSingleReq *) a_pc;
+ GLenum int_name ;
+ int value=0 ;
+ GLint answer_buf_room[200];
+ GLint *buf=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ a_pc += __GLX_SINGLE_HDR_SIZE;
+
+ int_name = *(GLenum*) (a_pc+0) ;
+ if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) {
+ EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ;
+ goto out ;
+ }
+ buf = __glXGetAnswerBuffer (a_cl, sizeof (value),
+ answer_buf_room,
+ sizeof (answer_buf_room),
+ 4) ;
+
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ;
+ res = BadAlloc ;
+ goto out ;
+ }
+ __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ ClientPtr client = a_cl->client;
+ xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
+ xGLXIsDirectReply reply;
+ int is_direct=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
+ EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
+ goto out ;
+ }
+ reply.isDirect = is_direct ;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c index f4a1b9d17..60f200629 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c @@ -1,1012 +1,1012 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@openedhand.com> - * - * Copyright © 2007 OpenedHand Ltd - * - * 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, and that the name of OpenedHand Ltd not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. OpenedHand Ltd makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - * Authors: - * Dodji Seketeli <dodji@openedhand.com> - */ -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif -/* - * including some server headers (like kdrive-config.h) - * might define the macro _XSERVER64 - * on 64 bits machines. That macro must _NOT_ be defined for Xlib - * client code, otherwise bad things happen. - * So let's undef that macro if necessary. - */ -#ifdef _XSERVER64 -#undef _XSERVER64 -#endif -#include <X11/Xutil.h> -#include <X11/Xlibint.h> -#include <X11/extensions/Xvlib.h> -#include <X11/extensions/Xvproto.h> -#include <X11/extensions/Xext.h> -#include <X11/extensions/extutil.h> -#define _HAVE_XALLOC_DECLS - -#include "hostx.h" -#include "ephyrhostvideo.h" -#include "ephyrlog.h" - -#ifndef TRUE -#define TRUE 1 -#endif /*TRUE*/ - -#ifndef FALSE -#define FALSE 0 -#endif /*FALSE*/ - -static XExtensionInfo _xv_info_data; -static XExtensionInfo *xv_info = &_xv_info_data; -static char *xv_extension_name = XvName; -static char *xv_error_string(Display *dpy, int code, XExtCodes *codes, - char * buf, int n); -static int xv_close_display(Display *dpy, XExtCodes *codes); -static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire); - -static XExtensionHooks xv_extension_hooks = { - NULL, /* create_gc */ - NULL, /* copy_gc */ - NULL, /* flush_gc */ - NULL, /* free_gc */ - NULL, /* create_font */ - NULL, /* free_font */ - xv_close_display, /* close_display */ - xv_wire_to_event, /* wire_to_event */ - NULL, /* event_to_wire */ - NULL, /* error */ - xv_error_string /* error_string */ -}; - - -static char *xv_error_list[] = -{ - "BadPort", /* XvBadPort */ - "BadEncoding", /* XvBadEncoding */ - "BadControl" /* XvBadControl */ -}; - - -#define XvCheckExtension(dpy, i, val) \ - XextCheckExtension(dpy, i, xv_extension_name, val) -#define XvGetReq(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\ - req->reqType = info->codes->major_opcode;\ - req->xvReqType = xv_##name; \ - req->length = (SIZEOF(xv##name##Req))>>2;\ - dpy->bufptr += SIZEOF(xv##name##Req);\ - dpy->request++ - -static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info) - - -static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info, - xv_extension_name, - &xv_extension_hooks, - XvNumEvents, NULL) - -static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name, - XvNumErrors, xv_error_list) - -struct _EphyrHostXVAdaptorArray { - XvAdaptorInfo *adaptors ; - unsigned int nb_adaptors ; -}; - -/*heavily copied from libx11*/ -#define BUFSIZE 2048 -static void -ephyrHostXVLogXErrorEvent (Display *a_display, - XErrorEvent *a_err_event, - FILE *a_fp) -{ - char buffer[BUFSIZ]; - char mesg[BUFSIZ]; - char number[32]; - const char *mtype = "XlibMessage"; - register _XExtension *ext = (_XExtension *)NULL; - _XExtension *bext = (_XExtension *)NULL; - Display *dpy = a_display ; - - XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ); - XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); - (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer); - XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", - mesg, BUFSIZ); - (void) fprintf(a_fp, mesg, a_err_event->request_code); - if (a_err_event->request_code < 128) { - sprintf(number, "%d", a_err_event->request_code); - XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); - } else { - for (ext = dpy->ext_procs; - ext && (ext->codes.major_opcode != a_err_event->request_code); - ext = ext->next) - ; - if (ext) - strcpy(buffer, ext->name); - else - buffer[0] = '\0'; - } - (void) fprintf(a_fp, " (%s)\n", buffer); - if (a_err_event->request_code >= 128) { - XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", - mesg, BUFSIZ); - fputs(" ", a_fp); - (void) fprintf(a_fp, mesg, a_err_event->minor_code); - if (ext) { - sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code); - XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); - (void) fprintf(a_fp, " (%s)", buffer); - } - fputs("\n", a_fp); - } - if (a_err_event->error_code >= 128) { - /* kludge, try to find the extension that caused it */ - buffer[0] = '\0'; - for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->error_string) - (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes, - buffer, BUFSIZ); - if (buffer[0]) { - bext = ext; - break; - } - if (ext->codes.first_error && - ext->codes.first_error < (int)a_err_event->error_code && - (!bext || ext->codes.first_error > bext->codes.first_error)) - bext = ext; - } - if (bext) - sprintf(buffer, "%s.%d", bext->name, - a_err_event->error_code - bext->codes.first_error); - else - strcpy(buffer, "Value"); - XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); - if (mesg[0]) { - fputs(" ", a_fp); - (void) fprintf(a_fp, mesg, a_err_event->resourceid); - fputs("\n", a_fp); - } - /* let extensions try to print the values */ - for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->error_values) - (*ext->error_values)(dpy, a_err_event, a_fp); - } - } else if ((a_err_event->error_code == BadWindow) || - (a_err_event->error_code == BadPixmap) || - (a_err_event->error_code == BadCursor) || - (a_err_event->error_code == BadFont) || - (a_err_event->error_code == BadDrawable) || - (a_err_event->error_code == BadColor) || - (a_err_event->error_code == BadGC) || - (a_err_event->error_code == BadIDChoice) || - (a_err_event->error_code == BadValue) || - (a_err_event->error_code == BadAtom)) { - if (a_err_event->error_code == BadValue) - XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", - mesg, BUFSIZ); - else if (a_err_event->error_code == BadAtom) - XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", - mesg, BUFSIZ); - else - XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", - mesg, BUFSIZ); - fputs(" ", a_fp); - (void) fprintf(a_fp, mesg, a_err_event->resourceid); - fputs("\n", a_fp); - } - XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", - mesg, BUFSIZ); - fputs(" ", a_fp); - (void) fprintf(a_fp, mesg, a_err_event->serial); - XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", - mesg, BUFSIZ); - fputs("\n ", a_fp); - (void) fprintf(a_fp, mesg, dpy->request); - fputs("\n", a_fp); -} - -static int -ephyrHostXVErrorHandler (Display *a_display, - XErrorEvent *a_error_event) -{ - EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ; - ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ; - return Success ; -} - -void -ephyrHostXVInit (void) -{ - static Bool s_initialized ; - - if (s_initialized) - return ; - XSetErrorHandler (ephyrHostXVErrorHandler) ; - s_initialized = TRUE ; -} - -Bool -ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) -{ - EphyrHostXVAdaptorArray *result=NULL ; - int ret=0 ; - Bool is_ok=FALSE ; - - EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ; - if (!result) - goto out ; - - ret = XvQueryAdaptors (hostx_get_display (), - DefaultRootWindow (hostx_get_display ()), - &result->nb_adaptors, - &result->adaptors) ; - if (ret != Success) { - EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ; - goto out ; - } - *a_adaptors = result ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -void -ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) -{ - if (!a_adaptors) - return ; - if (a_adaptors->adaptors) { - XvFreeAdaptorInfo (a_adaptors->adaptors) ; - a_adaptors->adaptors = NULL ; - a_adaptors->nb_adaptors = 0 ; - } - XFree (a_adaptors) ; -} - -int -ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; - return a_this->nb_adaptors ; -} - -EphyrHostXVAdaptor* -ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this, - int a_index) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ; - - if (a_index >= a_this->nb_adaptors) - return NULL ; - return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ; -} - -char -ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; - return ((XvAdaptorInfo*)a_this)->type ; -} - -const char* -ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ; - - return ((XvAdaptorInfo*)a_this)->name ; -} - -EphyrHostVideoFormat* -ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this, - int *a_nb_formats) -{ - EphyrHostVideoFormat *formats=NULL ; - int nb_formats=0, i=0 ; - XVisualInfo *visual_info, visual_info_template ; - int nb_visual_info ; - - EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ; - - nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ; - formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ; - for (i=0; i < nb_formats; i++) { - memset (&visual_info_template, 0, sizeof (visual_info_template)) ; - visual_info_template.visualid = - ((XvAdaptorInfo*)a_this)->formats[i].visual_id; - visual_info = XGetVisualInfo (hostx_get_display (), - VisualIDMask, - &visual_info_template, - &nb_visual_info) ; - formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ; - formats[i].visual_class = visual_info->class ; - XFree (visual_info) ; - } - if (a_nb_formats) - *a_nb_formats = nb_formats ; - return formats ; -} - -int -ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; - - return ((XvAdaptorInfo*)a_this)->num_ports ; -} - -int -ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; - - return ((XvAdaptorInfo*)a_this)->base_id ; -} - -Bool -ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this, - Bool *a_result) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; - - if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask) - *a_result = TRUE ; - else - *a_result = FALSE ; - return TRUE ; -} - -Bool -ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this, - Bool *a_result) -{ - if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask) - *a_result = TRUE ; - else - *a_result = FALSE ; - return TRUE ; -} - -Bool -ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this, - Bool *a_result) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; - - if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask) - *a_result = TRUE ; - else - *a_result = FALSE ; - return TRUE ; -} - -Bool -ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this, - Bool *a_result) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; - - if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask) - *a_result = TRUE ; - else - *a_result = FALSE ; - return TRUE ; -} - -Bool -ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this, - Bool *a_result) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; - - if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask) - *a_result = TRUE ; - else - *a_result = FALSE ; - return TRUE ; -} - -Bool -ephyrHostXVQueryEncodings (int a_port_id, - EphyrHostEncoding **a_encodings, - unsigned int *a_num_encodings) -{ - EphyrHostEncoding *encodings=NULL ; - XvEncodingInfo *encoding_info=NULL ; - unsigned int num_encodings=0, i; - int ret=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ; - - ret = XvQueryEncodings (hostx_get_display (), - a_port_id, - &num_encodings, - &encoding_info) ; - if (num_encodings && encoding_info) { - encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ; - for (i=0; i<num_encodings; i++) { - encodings[i].id = encoding_info[i].encoding_id ; - encodings[i].name = strdup (encoding_info[i].name) ; - encodings[i].width = encoding_info[i].width ; - encodings[i].height = encoding_info[i].height ; - encodings[i].rate.numerator = encoding_info[i].rate.numerator ; - encodings[i].rate.denominator = encoding_info[i].rate.denominator ; - } - } - if (encoding_info) { - XvFreeEncodingInfo (encoding_info) ; - encoding_info = NULL ; - } - *a_encodings = encodings ; - *a_num_encodings = num_encodings ; - - if (ret != Success) - return FALSE ; - return TRUE ; -} - -void -ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings, - int a_num_encodings) -{ - int i=0 ; - - if (!a_encodings) - return ; - for (i=0; i < a_num_encodings; i++) { - xfree (a_encodings[i].name) ; - a_encodings[i].name = NULL ; - } - xfree (a_encodings) ; -} - -void -ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) -{ - if (!a_attributes) - return ; - XFree (a_attributes) ; -} - -Bool -ephyrHostXVQueryPortAttributes (int a_port_id, - EphyrHostAttribute **a_attributes, - int *a_num_attributes) -{ - EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ; - - *a_attributes = - (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (), - a_port_id, - a_num_attributes); - - return TRUE ; -} - -Bool -ephyrHostXVQueryImageFormats (int a_port_id, - EphyrHostImageFormat **a_formats, - int *a_num_format) -{ - XvImageFormatValues *result=NULL ; - - EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ; - - result = XvListImageFormats (hostx_get_display (), - a_port_id, - a_num_format) ; - *a_formats = (EphyrHostImageFormat*) result ; - return TRUE ; - -} - -Bool -ephyrHostXVSetPortAttribute (int a_port_id, - int a_atom, - int a_attr_value) -{ - int res=Success ; - - EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n", - a_atom, - XGetAtomName (hostx_get_display (), a_atom), - a_attr_value) ; - - res = XvSetPortAttribute (hostx_get_display (), - a_port_id, - a_atom, - a_attr_value) ; - if (res != Success) { - EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ; - return FALSE ; - } - XFlush (hostx_get_display ()) ; - EPHYR_LOG ("leave\n") ; - - return TRUE ; -} - -Bool -ephyrHostXVGetPortAttribute (int a_port_id, - int a_atom, - int *a_attr_value) -{ - int res=Success ; - Bool ret=FALSE ; - - EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ; - - EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n", - a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ; - - res = XvGetPortAttribute (hostx_get_display (), - a_port_id, - a_atom, - a_attr_value) ; - if (res != Success) { - EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ; - goto out ; - } - EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ; - - ret = TRUE ; - -out: - EPHYR_LOG ("leave\n") ; - return ret ; -} - -Bool -ephyrHostXVQueryBestSize (int a_port_id, - Bool a_motion, - unsigned int a_frame_w, - unsigned int a_frame_h, - unsigned int a_drw_w, - unsigned int a_drw_h, - unsigned int *a_actual_w, - unsigned int *a_actual_h) -{ - int res=0 ; - Bool is_ok=FALSE ; - - EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ; - - EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n", - a_frame_w, a_frame_h, - a_drw_w, a_drw_h) ; - - res = XvQueryBestSize (hostx_get_display (), - a_port_id, - a_motion, - a_frame_w, a_frame_h, - a_drw_w, a_drw_h, - a_actual_w, a_actual_h) ; - if (res != Success) { - EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ; - goto out ; - } - XSync (hostx_get_display (), FALSE) ; - - EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -static Bool -xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) -{ - XExtDisplayInfo *info = xv_find_display (dpy); - XvEvent *re = (XvEvent *)host; - xvEvent *event = (xvEvent *)wire; - - XvCheckExtension(dpy, info, False); - - switch ((event->u.u.type & 0x7F) - info->codes->first_event) { - case XvVideoNotify: - re->xvvideo.type = event->u.u.type & 0x7f; - re->xvvideo.serial = - _XSetLastRequestRead(dpy, (xGenericReply *)event); - re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); - re->xvvideo.display = dpy; - re->xvvideo.time = event->u.videoNotify.time; - re->xvvideo.reason = event->u.videoNotify.reason; - re->xvvideo.drawable = event->u.videoNotify.drawable; - re->xvvideo.port_id = event->u.videoNotify.port; - break; - case XvPortNotify: - re->xvport.type = event->u.u.type & 0x7f; - re->xvport.serial = - _XSetLastRequestRead(dpy, (xGenericReply *)event); - re->xvport.send_event = ((event->u.u.type & 0x80) != 0); - re->xvport.display = dpy; - re->xvport.time = event->u.portNotify.time; - re->xvport.port_id = event->u.portNotify.port; - re->xvport.attribute = event->u.portNotify.attribute; - re->xvport.value = event->u.portNotify.value; - break; - default: - return False; - } - - return True ; -} - -Bool -ephyrHostXVQueryImageAttributes (int a_port_id, - int a_image_id /*image fourcc code*/, - unsigned short *a_width, - unsigned short *a_height, - int *a_image_size, - int *a_pitches, - int *a_offsets) -{ - Display *dpy = hostx_get_display () ; - Bool ret=FALSE ; - XExtDisplayInfo *info = xv_find_display (dpy); - xvQueryImageAttributesReq *req=NULL; - xvQueryImageAttributesReply rep; - - EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ; - EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ; - EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ; - - XvCheckExtension (dpy, info, FALSE); - - LockDisplay (dpy); - - XvGetReq (QueryImageAttributes, req); - req->id = a_image_id; - req->port = a_port_id; - req->width = *a_width; - req->height = *a_height; - /* - * read the reply - */ - if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { - EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ; - goto out ; - } - if (a_pitches && a_offsets) { - _XRead (dpy, - (char*)a_pitches, - rep.num_planes << 2); - _XRead (dpy, - (char*)a_offsets, - rep.num_planes << 2); - } else { - _XEatData(dpy, rep.length << 2); - } - *a_width = rep.width ; - *a_height = rep.height ; - *a_image_size = rep.data_size ; - - ret = TRUE ; - -out: - UnlockDisplay (dpy) ; - SyncHandle (); - return ret ; -} - -Bool -ephyrHostGetAtom (const char* a_name, - Bool a_create_if_not_exists, - int *a_atom) -{ - int atom=None ; - - EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ; - - atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists); - if (atom == None) { - return FALSE ; - } - *a_atom = atom ; - return TRUE ; -} - -char* -ephyrHostGetAtomName (int a_atom) -{ - return XGetAtomName (hostx_get_display (), a_atom) ; -} - -void -ephyrHostFree (void *a_pointer) -{ - if (a_pointer) - XFree (a_pointer) ; -} - -Bool -ephyrHostXVPutImage (int a_screen_num, - int a_port_id, - int a_image_id, - int a_drw_x, - int a_drw_y, - int a_drw_w, - int a_drw_h, - int a_src_x, - int a_src_y, - int a_src_w, - int a_src_h, - int a_image_width, - int a_image_height, - unsigned char *a_buf, - EphyrHostBox *a_clip_rects, - int a_clip_rect_nums ) -{ - Bool is_ok=TRUE ; - XvImage *xv_image=NULL ; - GC gc=0 ; - XGCValues gc_values; - Display *dpy = hostx_get_display () ; - XRectangle *rects=NULL ; - int res = 0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ; - - EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ; - - memset (&gc_values, 0, sizeof (gc_values)) ; - gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); - if (!gc) { - EPHYR_LOG_ERROR ("failed to create gc \n") ; - goto out ; - } - xv_image = (XvImage*) XvCreateImage (hostx_get_display (), - a_port_id, a_image_id, - NULL, a_image_width, a_image_height) ; - if (!xv_image) { - EPHYR_LOG_ERROR ("failed to create image\n") ; - goto out ; - } - xv_image->data = (char*)a_buf ; - if (a_clip_rect_nums) { - int i=0 ; - rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ; - for (i=0; i < a_clip_rect_nums; i++) { - rects[i].x = a_clip_rects[i].x1 ; - rects[i].y = a_clip_rects[i].y1 ; - rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1; - rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1; - EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n", - rects[i].x, rects[i].y, - rects[i].width, rects[i].height) ; - } - XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ; - /*this always returns 1*/ - } - res = XvPutImage (dpy, a_port_id, - hostx_get_window (a_screen_num), - gc, xv_image, - a_src_x, a_src_y, a_src_w, a_src_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; - if (res != Success) { - EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ; - goto out ; - } - is_ok = TRUE ; - -out: - if (xv_image) { - XFree (xv_image) ; - xv_image = NULL ; - } - if (gc) { - XFreeGC (dpy, gc) ; - gc = NULL ; - } - if (rects) { - free (rects) ; - rects = NULL ; - } - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -Bool -ephyrHostXVPutVideo (int a_screen_num, int a_port_id, - int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, - int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) -{ - Bool is_ok=FALSE ; - int res=FALSE ; - GC gc=0 ; - XGCValues gc_values; - Display *dpy=hostx_get_display () ; - - EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; - - gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); - if (!gc) { - EPHYR_LOG_ERROR ("failed to create gc \n") ; - goto out ; - } - res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; - - if (res != Success) { - EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ; - goto out ; - } - - is_ok = TRUE ; - -out: - if (gc) { - XFreeGC (dpy, gc) ; - gc = NULL ; - } - return is_ok ; -} - -Bool -ephyrHostXVGetVideo (int a_screen_num, int a_port_id, - int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, - int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) -{ - Bool is_ok=FALSE ; - int res=FALSE ; - GC gc=0 ; - XGCValues gc_values; - Display *dpy=hostx_get_display () ; - - EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; - - gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); - if (!gc) { - EPHYR_LOG_ERROR ("failed to create gc \n") ; - goto out ; - } - res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; - - if (res != Success) { - EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ; - goto out ; - } - - is_ok = TRUE ; - -out: - if (gc) { - XFreeGC (dpy, gc) ; - gc = NULL ; - } - return is_ok ; -} - -Bool -ephyrHostXVPutStill (int a_screen_num, int a_port_id, - int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, - int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) -{ - Bool is_ok=FALSE ; - int res=FALSE ; - GC gc=0 ; - XGCValues gc_values; - Display *dpy=hostx_get_display () ; - - EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; - - gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); - if (!gc) { - EPHYR_LOG_ERROR ("failed to create gc \n") ; - goto out ; - } - res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; - - if (res != Success) { - EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ; - goto out ; - } - - is_ok = TRUE ; - -out: - if (gc) { - XFreeGC (dpy, gc) ; - gc = NULL ; - } - return is_ok ; -} - -Bool -ephyrHostXVGetStill (int a_screen_num, int a_port_id, - int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, - int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) -{ - Bool is_ok=FALSE ; - int res=FALSE ; - GC gc=0 ; - XGCValues gc_values; - Display *dpy=hostx_get_display () ; - - EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; - - gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); - if (!gc) { - EPHYR_LOG_ERROR ("failed to create gc \n") ; - goto out ; - } - res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; - - if (res != Success) { - EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ; - goto out ; - } - - is_ok = TRUE ; - -out: - if (gc) { - XFreeGC (dpy, gc) ; - gc = NULL ; - } - return is_ok ; -} - -Bool -ephyrHostXVStopVideo (int a_screen_num, int a_port_id) -{ - int ret=0 ; - Bool is_ok=FALSE ; - Display *dpy = hostx_get_display () ; - - EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ; - if (ret != Success) { - EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ; - goto out ; - } - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+/*
+ * including some server headers (like kdrive-config.h)
+ * might define the macro _XSERVER64
+ * on 64 bits machines. That macro must _NOT_ be defined for Xlib
+ * client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/Xvproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#define _HAVE_XALLOC_DECLS
+
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+#include "ephyrlog.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif /*TRUE*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif /*FALSE*/
+
+static XExtensionInfo _xv_info_data;
+static XExtensionInfo *xv_info = &_xv_info_data;
+static char *xv_extension_name = XvName;
+static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
+ char * buf, int n);
+static int xv_close_display(Display *dpy, XExtCodes *codes);
+static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
+
+static XExtensionHooks xv_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ xv_close_display, /* close_display */
+ xv_wire_to_event, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ xv_error_string /* error_string */
+};
+
+
+static char *xv_error_list[] =
+{
+ "BadPort", /* XvBadPort */
+ "BadEncoding", /* XvBadEncoding */
+ "BadControl" /* XvBadControl */
+};
+
+
+#define XvCheckExtension(dpy, i, val) \
+ XextCheckExtension(dpy, i, xv_extension_name, val)
+#define XvGetReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = info->codes->major_opcode;\
+ req->xvReqType = xv_##name; \
+ req->length = (SIZEOF(xv##name##Req))>>2;\
+ dpy->bufptr += SIZEOF(xv##name##Req);\
+ dpy->request++
+
+static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
+
+
+static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
+ xv_extension_name,
+ &xv_extension_hooks,
+ XvNumEvents, NULL)
+
+static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
+ XvNumErrors, xv_error_list)
+
+struct _EphyrHostXVAdaptorArray {
+ XvAdaptorInfo *adaptors ;
+ unsigned int nb_adaptors ;
+};
+
+/*heavily copied from libx11*/
+#define BUFSIZE 2048
+static void
+ephyrHostXVLogXErrorEvent (Display *a_display,
+ XErrorEvent *a_err_event,
+ FILE *a_fp)
+{
+ char buffer[BUFSIZ];
+ char mesg[BUFSIZ];
+ char number[32];
+ const char *mtype = "XlibMessage";
+ register _XExtension *ext = (_XExtension *)NULL;
+ _XExtension *bext = (_XExtension *)NULL;
+ Display *dpy = a_display ;
+
+ XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
+ XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+ (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ mesg, BUFSIZ);
+ (void) fprintf(a_fp, mesg, a_err_event->request_code);
+ if (a_err_event->request_code < 128) {
+ sprintf(number, "%d", a_err_event->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+ } else {
+ for (ext = dpy->ext_procs;
+ ext && (ext->codes.major_opcode != a_err_event->request_code);
+ ext = ext->next)
+ ;
+ if (ext)
+ strcpy(buffer, ext->name);
+ else
+ buffer[0] = '\0';
+ }
+ (void) fprintf(a_fp, " (%s)\n", buffer);
+ if (a_err_event->request_code >= 128) {
+ XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->minor_code);
+ if (ext) {
+ sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+ (void) fprintf(a_fp, " (%s)", buffer);
+ }
+ fputs("\n", a_fp);
+ }
+ if (a_err_event->error_code >= 128) {
+ /* kludge, try to find the extension that caused it */
+ buffer[0] = '\0';
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_string)
+ (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
+ buffer, BUFSIZ);
+ if (buffer[0]) {
+ bext = ext;
+ break;
+ }
+ if (ext->codes.first_error &&
+ ext->codes.first_error < (int)a_err_event->error_code &&
+ (!bext || ext->codes.first_error > bext->codes.first_error))
+ bext = ext;
+ }
+ if (bext)
+ sprintf(buffer, "%s.%d", bext->name,
+ a_err_event->error_code - bext->codes.first_error);
+ else
+ strcpy(buffer, "Value");
+ XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+ if (mesg[0]) {
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+ fputs("\n", a_fp);
+ }
+ /* let extensions try to print the values */
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_values)
+ (*ext->error_values)(dpy, a_err_event, a_fp);
+ }
+ } else if ((a_err_event->error_code == BadWindow) ||
+ (a_err_event->error_code == BadPixmap) ||
+ (a_err_event->error_code == BadCursor) ||
+ (a_err_event->error_code == BadFont) ||
+ (a_err_event->error_code == BadDrawable) ||
+ (a_err_event->error_code == BadColor) ||
+ (a_err_event->error_code == BadGC) ||
+ (a_err_event->error_code == BadIDChoice) ||
+ (a_err_event->error_code == BadValue) ||
+ (a_err_event->error_code == BadAtom)) {
+ if (a_err_event->error_code == BadValue)
+ XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+ mesg, BUFSIZ);
+ else if (a_err_event->error_code == BadAtom)
+ XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+ mesg, BUFSIZ);
+ else
+ XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+ fputs("\n", a_fp);
+ }
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->serial);
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+ mesg, BUFSIZ);
+ fputs("\n ", a_fp);
+ (void) fprintf(a_fp, mesg, dpy->request);
+ fputs("\n", a_fp);
+}
+
+static int
+ephyrHostXVErrorHandler (Display *a_display,
+ XErrorEvent *a_error_event)
+{
+ EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
+ ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
+ return Success ;
+}
+
+void
+ephyrHostXVInit (void)
+{
+ static Bool s_initialized ;
+
+ if (s_initialized)
+ return ;
+ XSetErrorHandler (ephyrHostXVErrorHandler) ;
+ s_initialized = TRUE ;
+}
+
+Bool
+ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
+{
+ EphyrHostXVAdaptorArray *result=NULL ;
+ int ret=0 ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
+ if (!result)
+ goto out ;
+
+ ret = XvQueryAdaptors (hostx_get_display (),
+ DefaultRootWindow (hostx_get_display ()),
+ &result->nb_adaptors,
+ &result->adaptors) ;
+ if (ret != Success) {
+ EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
+ goto out ;
+ }
+ *a_adaptors = result ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+void
+ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
+{
+ if (!a_adaptors)
+ return ;
+ if (a_adaptors->adaptors) {
+ XvFreeAdaptorInfo (a_adaptors->adaptors) ;
+ a_adaptors->adaptors = NULL ;
+ a_adaptors->nb_adaptors = 0 ;
+ }
+ XFree (a_adaptors) ;
+}
+
+int
+ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+ return a_this->nb_adaptors ;
+}
+
+EphyrHostXVAdaptor*
+ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+ int a_index)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ if (a_index >= a_this->nb_adaptors)
+ return NULL ;
+ return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
+}
+
+char
+ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+ return ((XvAdaptorInfo*)a_this)->type ;
+}
+
+const char*
+ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ return ((XvAdaptorInfo*)a_this)->name ;
+}
+
+EphyrHostVideoFormat*
+ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
+ int *a_nb_formats)
+{
+ EphyrHostVideoFormat *formats=NULL ;
+ int nb_formats=0, i=0 ;
+ XVisualInfo *visual_info, visual_info_template ;
+ int nb_visual_info ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
+ formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
+ for (i=0; i < nb_formats; i++) {
+ memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
+ visual_info_template.visualid =
+ ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
+ visual_info = XGetVisualInfo (hostx_get_display (),
+ VisualIDMask,
+ &visual_info_template,
+ &nb_visual_info) ;
+ formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
+ formats[i].visual_class = visual_info->class ;
+ XFree (visual_info) ;
+ }
+ if (a_nb_formats)
+ *a_nb_formats = nb_formats ;
+ return formats ;
+}
+
+int
+ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+ return ((XvAdaptorInfo*)a_this)->num_ports ;
+}
+
+int
+ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+ return ((XvAdaptorInfo*)a_this)->base_id ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVQueryEncodings (int a_port_id,
+ EphyrHostEncoding **a_encodings,
+ unsigned int *a_num_encodings)
+{
+ EphyrHostEncoding *encodings=NULL ;
+ XvEncodingInfo *encoding_info=NULL ;
+ unsigned int num_encodings=0, i;
+ int ret=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
+
+ ret = XvQueryEncodings (hostx_get_display (),
+ a_port_id,
+ &num_encodings,
+ &encoding_info) ;
+ if (num_encodings && encoding_info) {
+ encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ;
+ for (i=0; i<num_encodings; i++) {
+ encodings[i].id = encoding_info[i].encoding_id ;
+ encodings[i].name = strdup (encoding_info[i].name) ;
+ encodings[i].width = encoding_info[i].width ;
+ encodings[i].height = encoding_info[i].height ;
+ encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
+ encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
+ }
+ }
+ if (encoding_info) {
+ XvFreeEncodingInfo (encoding_info) ;
+ encoding_info = NULL ;
+ }
+ *a_encodings = encodings ;
+ *a_num_encodings = num_encodings ;
+
+ if (ret != Success)
+ return FALSE ;
+ return TRUE ;
+}
+
+void
+ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+ int a_num_encodings)
+{
+ int i=0 ;
+
+ if (!a_encodings)
+ return ;
+ for (i=0; i < a_num_encodings; i++) {
+ free(a_encodings[i].name) ;
+ a_encodings[i].name = NULL ;
+ }
+ free(a_encodings) ;
+}
+
+void
+ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
+{
+ if (!a_attributes)
+ return ;
+ XFree (a_attributes) ;
+}
+
+Bool
+ephyrHostXVQueryPortAttributes (int a_port_id,
+ EphyrHostAttribute **a_attributes,
+ int *a_num_attributes)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
+
+ *a_attributes =
+ (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
+ a_port_id,
+ a_num_attributes);
+
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVQueryImageFormats (int a_port_id,
+ EphyrHostImageFormat **a_formats,
+ int *a_num_format)
+{
+ XvImageFormatValues *result=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
+
+ result = XvListImageFormats (hostx_get_display (),
+ a_port_id,
+ a_num_format) ;
+ *a_formats = (EphyrHostImageFormat*) result ;
+ return TRUE ;
+
+}
+
+Bool
+ephyrHostXVSetPortAttribute (int a_port_id,
+ int a_atom,
+ int a_attr_value)
+{
+ int res=Success ;
+
+ EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
+ a_atom,
+ XGetAtomName (hostx_get_display (), a_atom),
+ a_attr_value) ;
+
+ res = XvSetPortAttribute (hostx_get_display (),
+ a_port_id,
+ a_atom,
+ a_attr_value) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
+ return FALSE ;
+ }
+ XFlush (hostx_get_display ()) ;
+ EPHYR_LOG ("leave\n") ;
+
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVGetPortAttribute (int a_port_id,
+ int a_atom,
+ int *a_attr_value)
+{
+ int res=Success ;
+ Bool ret=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
+
+ EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
+ a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
+
+ res = XvGetPortAttribute (hostx_get_display (),
+ a_port_id,
+ a_atom,
+ a_attr_value) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
+ goto out ;
+ }
+ EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
+
+ ret = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return ret ;
+}
+
+Bool
+ephyrHostXVQueryBestSize (int a_port_id,
+ Bool a_motion,
+ unsigned int a_frame_w,
+ unsigned int a_frame_h,
+ unsigned int a_drw_w,
+ unsigned int a_drw_h,
+ unsigned int *a_actual_w,
+ unsigned int *a_actual_h)
+{
+ int res=0 ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
+
+ EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
+ a_frame_w, a_frame_h,
+ a_drw_w, a_drw_h) ;
+
+ res = XvQueryBestSize (hostx_get_display (),
+ a_port_id,
+ a_motion,
+ a_frame_w, a_frame_h,
+ a_drw_w, a_drw_h,
+ a_actual_w, a_actual_h) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
+ goto out ;
+ }
+ XSync (hostx_get_display (), FALSE) ;
+
+ EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
+{
+ XExtDisplayInfo *info = xv_find_display (dpy);
+ XvEvent *re = (XvEvent *)host;
+ xvEvent *event = (xvEvent *)wire;
+
+ XvCheckExtension(dpy, info, False);
+
+ switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
+ case XvVideoNotify:
+ re->xvvideo.type = event->u.u.type & 0x7f;
+ re->xvvideo.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvvideo.display = dpy;
+ re->xvvideo.time = event->u.videoNotify.time;
+ re->xvvideo.reason = event->u.videoNotify.reason;
+ re->xvvideo.drawable = event->u.videoNotify.drawable;
+ re->xvvideo.port_id = event->u.videoNotify.port;
+ break;
+ case XvPortNotify:
+ re->xvport.type = event->u.u.type & 0x7f;
+ re->xvport.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvport.display = dpy;
+ re->xvport.time = event->u.portNotify.time;
+ re->xvport.port_id = event->u.portNotify.port;
+ re->xvport.attribute = event->u.portNotify.attribute;
+ re->xvport.value = event->u.portNotify.value;
+ break;
+ default:
+ return False;
+ }
+
+ return True ;
+}
+
+Bool
+ephyrHostXVQueryImageAttributes (int a_port_id,
+ int a_image_id /*image fourcc code*/,
+ unsigned short *a_width,
+ unsigned short *a_height,
+ int *a_image_size,
+ int *a_pitches,
+ int *a_offsets)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool ret=FALSE ;
+ XExtDisplayInfo *info = xv_find_display (dpy);
+ xvQueryImageAttributesReq *req=NULL;
+ xvQueryImageAttributesReply rep;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
+
+ XvCheckExtension (dpy, info, FALSE);
+
+ LockDisplay (dpy);
+
+ XvGetReq (QueryImageAttributes, req);
+ req->id = a_image_id;
+ req->port = a_port_id;
+ req->width = *a_width;
+ req->height = *a_height;
+ /*
+ * read the reply
+ */
+ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
+ EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
+ goto out ;
+ }
+ if (a_pitches && a_offsets) {
+ _XRead (dpy,
+ (char*)a_pitches,
+ rep.num_planes << 2);
+ _XRead (dpy,
+ (char*)a_offsets,
+ rep.num_planes << 2);
+ } else {
+ _XEatData(dpy, rep.length << 2);
+ }
+ *a_width = rep.width ;
+ *a_height = rep.height ;
+ *a_image_size = rep.data_size ;
+
+ ret = TRUE ;
+
+out:
+ UnlockDisplay (dpy) ;
+ SyncHandle ();
+ return ret ;
+}
+
+Bool
+ephyrHostGetAtom (const char* a_name,
+ Bool a_create_if_not_exists,
+ int *a_atom)
+{
+ int atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
+
+ atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
+ if (atom == None) {
+ return FALSE ;
+ }
+ *a_atom = atom ;
+ return TRUE ;
+}
+
+char*
+ephyrHostGetAtomName (int a_atom)
+{
+ return XGetAtomName (hostx_get_display (), a_atom) ;
+}
+
+void
+ephyrHostFree (void *a_pointer)
+{
+ if (a_pointer)
+ XFree (a_pointer) ;
+}
+
+Bool
+ephyrHostXVPutImage (int a_screen_num,
+ int a_port_id,
+ int a_image_id,
+ int a_drw_x,
+ int a_drw_y,
+ int a_drw_w,
+ int a_drw_h,
+ int a_src_x,
+ int a_src_y,
+ int a_src_w,
+ int a_src_h,
+ int a_image_width,
+ int a_image_height,
+ unsigned char *a_buf,
+ EphyrHostBox *a_clip_rects,
+ int a_clip_rect_nums )
+{
+ Bool is_ok=TRUE ;
+ XvImage *xv_image=NULL ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy = hostx_get_display () ;
+ XRectangle *rects=NULL ;
+ int res = 0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
+
+ EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
+
+ memset (&gc_values, 0, sizeof (gc_values)) ;
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
+ a_port_id, a_image_id,
+ NULL, a_image_width, a_image_height) ;
+ if (!xv_image) {
+ EPHYR_LOG_ERROR ("failed to create image\n") ;
+ goto out ;
+ }
+ xv_image->data = (char*)a_buf ;
+ if (a_clip_rect_nums) {
+ int i=0 ;
+ rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
+ for (i=0; i < a_clip_rect_nums; i++) {
+ rects[i].x = a_clip_rects[i].x1 ;
+ rects[i].y = a_clip_rects[i].y1 ;
+ rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
+ rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
+ EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height) ;
+ }
+ XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
+ /*this always returns 1*/
+ }
+ res = XvPutImage (dpy, a_port_id,
+ hostx_get_window (a_screen_num),
+ gc, xv_image,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ if (xv_image) {
+ XFree (xv_image) ;
+ xv_image = NULL ;
+ }
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ if (rects) {
+ free (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVPutStill (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVGetStill (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
+{
+ int ret=0 ;
+ Bool is_ok=FALSE ;
+ Display *dpy = hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
+ if (ret != Success) {
+ EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c index 6624ab98a..14213c966 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c @@ -1,1273 +1,1273 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@openedhand.com> - * - * Copyright © 2007 OpenedHand Ltd - * - * 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, and that the name of OpenedHand Ltd not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. OpenedHand Ltd makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - * Authors: - * Dodji Seketeli <dodji@openedhand.com> - */ - -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif -#include <string.h> -#include <X11/extensions/Xv.h> -#include "ephyrlog.h" -#include "kdrive.h" -#include "kxv.h" -#include "ephyr.h" -#include "hostx.h" -#include "ephyrhostvideo.h" - -struct _EphyrXVPriv { - EphyrHostXVAdaptorArray *host_adaptors ; - KdVideoAdaptorPtr adaptors ; - int num_adaptors ; -}; -typedef struct _EphyrXVPriv EphyrXVPriv ; - -struct _EphyrPortPriv { - int port_number ; - KdVideoAdaptorPtr current_adaptor ; - EphyrXVPriv *xv_priv; - unsigned char *image_buf ; - int image_buf_size ; - int image_id ; - int drw_x, drw_y, drw_w, drw_h ; - int src_x, src_y, src_w, src_h ; - int image_width, image_height ; -}; -typedef struct _EphyrPortPriv EphyrPortPriv ; - -static Bool DoSimpleClip (BoxPtr a_dst_drw, - BoxPtr a_clipper, - BoxPtr a_result) ; - -static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ; - -/* -static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ; -*/ - -static EphyrXVPriv* ephyrXVPrivNew (void) ; -static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ; -static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ; -static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ; -static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this, - ScreenPtr a_screen) ; - -static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs, - int a_attrs_len, - const char *a_attr_name, - int a_attr_value, - Bool *a_is_valid) ; - -static Bool ephyrXVPrivGetImageBufSize (int a_port_id, - int a_image_id, - unsigned short a_width, - unsigned short a_height, - int *a_size) ; - -static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv, - const unsigned char *a_image, - int a_image_len) ; - -static void ephyrStopVideo (KdScreenInfo *a_info, - pointer a_xv_priv, - Bool a_exit); - -static int ephyrSetPortAttribute (KdScreenInfo *a_info, - Atom a_attr_name, - int a_attr_value, - pointer a_port_priv); - -static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info, - Atom a_attr_name, - int *a_attr_value, - pointer a_port_priv); - -static void ephyrQueryBestSize (KdScreenInfo *a_info, - Bool a_motion, - short a_src_w, - short a_src_h, - short a_drw_w, - short a_drw_h, - unsigned int *a_prefered_w, - unsigned int *a_prefered_h, - pointer a_port_priv); - -static int ephyrPutImage (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_src_x, - short a_src_y, - short a_drw_x, - short a_drw_y, - short a_src_w, - short a_src_h, - short a_drw_w, - short a_drw_h, - int a_id, - unsigned char *a_buf, - short a_width, - short a_height, - Bool a_sync, - RegionPtr a_clipping_region, - pointer a_port_priv); - -static int ephyrReputImage (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_drw_x, - short a_drw_y, - RegionPtr a_clipping_region, - pointer a_port_priv) ; - -static int ephyrPutVideo (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clip_region, - pointer a_port_priv) ; - -static int ephyrGetVideo (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clip_region, - pointer a_port_priv) ; - -static int ephyrPutStill (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clip_region, - pointer a_port_priv) ; - -static int ephyrGetStill (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clip_region, - pointer a_port_priv) ; - -static int ephyrQueryImageAttributes (KdScreenInfo *a_info, - int a_id, - unsigned short *a_w, - unsigned short *a_h, - int *a_pitches, - int *a_offsets); -static int s_base_port_id ; - -/************** - * <helpers> - * ************/ - -static Bool -DoSimpleClip (BoxPtr a_dst_box, - BoxPtr a_clipper, - BoxPtr a_result) -{ - BoxRec dstClippedBox ; - - EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ; - - /* - * setup the clipbox inside the destination. - */ - dstClippedBox.x1 = a_dst_box->x1 ; - dstClippedBox.x2 = a_dst_box->x2 ; - dstClippedBox.y1 = a_dst_box->y1 ; - dstClippedBox.y2 = a_dst_box->y2 ; - - /* - * if the cliper leftmost edge is inside - * the destination area then the leftmost edge of the resulting - * clipped box is the leftmost edge of the cliper. - */ - if (a_clipper->x1 > dstClippedBox.x1) - dstClippedBox.x1 = a_clipper->x1 ; - - /* - * if the cliper top edge is inside the destination area - * then the bottom horizontal edge of the resulting clipped box - * is the bottom edge of the cliper - */ - if (a_clipper->y1 > dstClippedBox.y1) - dstClippedBox.y1 = a_clipper->y1 ; - - /*ditto for right edge*/ - if (a_clipper->x2 < dstClippedBox.x2) - dstClippedBox.x2 = a_clipper->x2 ; - - /*ditto for bottom edge*/ - if (a_clipper->y2 < dstClippedBox.y2) - dstClippedBox.y2 = a_clipper->y2 ; - - memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ; - return TRUE ; -} - -static Bool -ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) -{ - const char *atom_name=NULL; - int host_atom=None ; - - EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ; - - if (!ValidAtom (a_local_atom)) - return FALSE ; - - atom_name = NameForAtom (a_local_atom) ; - - if (!atom_name) - return FALSE ; - - if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) { - EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n", - atom_name) ; - return FALSE ; - } - *a_host_atom = host_atom ; - return TRUE ; -} - -/* - Not used yed. -static Bool -ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) -{ - Bool is_ok=FALSE ; - char *atom_name=NULL ; - int atom=None ; - - EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ; - - atom_name = ephyrHostGetAtomName (a_host_atom) ; - if (!atom_name) - goto out ; - - atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ; - if (atom == None) - goto out ; - - *a_local_atom = atom ; - is_ok = TRUE ; - -out: - if (atom_name) { - ephyrHostFree (atom_name) ; - } - return is_ok ; -} -*/ - -/************** - *</helpers> - * ************/ - -Bool -ephyrInitVideo (ScreenPtr pScreen) -{ - Bool is_ok = FALSE ; - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - static EphyrXVPriv *xv_priv; - - EPHYR_LOG ("enter\n") ; - - if (screen->fb.bitsPerPixel == 8) { - EPHYR_LOG_ERROR ("8 bits depth not supported\n") ; - return FALSE ; - } - - if (!xv_priv) { - xv_priv = ephyrXVPrivNew () ; - } - if (!xv_priv) { - EPHYR_LOG_ERROR ("failed to create xv_priv\n") ; - goto out ; - } - - if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) { - EPHYR_LOG_ERROR ("failed to register adaptors\n") ; - goto out ; - } - is_ok = TRUE ; - -out: - return is_ok ; -} - -static EphyrXVPriv* -ephyrXVPrivNew (void) -{ - EphyrXVPriv *xv_priv=NULL ; - - EPHYR_LOG ("enter\n") ; - - xv_priv = xcalloc (1, sizeof (EphyrXVPriv)) ; - if (!xv_priv) { - EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ; - goto error ; - } - - ephyrHostXVInit () ; - - if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) { - EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ; - goto error ; - } - if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) { - EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ; - goto error ; - } - - EPHYR_LOG ("leave\n") ; - return xv_priv ; - -error: - if (xv_priv) { - ephyrXVPrivDelete (xv_priv) ; - xv_priv = NULL ; - } - return NULL ; -} - -static void -ephyrXVPrivDelete (EphyrXVPriv *a_this) -{ - EPHYR_LOG ("enter\n") ; - - if (!a_this) - return ; - if (a_this->host_adaptors) { - ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ; - a_this->host_adaptors = NULL ; - } - xfree (a_this->adaptors) ; - a_this->adaptors = NULL ; - xfree (a_this) ; - EPHYR_LOG ("leave\n") ; -} - -static KdVideoEncodingPtr -videoEncodingDup (EphyrHostEncoding *a_encodings, - int a_num_encodings) -{ - KdVideoEncodingPtr result = NULL ; - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ; - - result = xcalloc (a_num_encodings, sizeof (KdVideoEncodingRec)) ; - for (i=0 ; i < a_num_encodings; i++) { - result[i].id = a_encodings[i].id ; - result[i].name = strdup (a_encodings[i].name) ; - result[i].width = a_encodings[i].width ; - result[i].height = a_encodings[i].height ; - result[i].rate.numerator = a_encodings[i].rate.numerator ; - result[i].rate.denominator = a_encodings[i].rate.denominator ; - } - return result ; -} - -static KdAttributePtr -portAttributesDup (EphyrHostAttribute *a_encodings, - int a_num_encodings) -{ - int i=0 ; - KdAttributePtr result=NULL ; - - EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ; - - result = xcalloc (a_num_encodings, sizeof (KdAttributeRec)) ; - if (!result) { - EPHYR_LOG_ERROR ("failed to allocate attributes\n") ; - return NULL ; - } - for (i=0; i < a_num_encodings; i++) { - result[i].flags = a_encodings[i].flags ; - result[i].min_value = a_encodings[i].min_value ; - result[i].max_value = a_encodings[i].max_value ; - result[i].name = strdup (a_encodings[i].name) ; - } - return result ; -} - -static Bool -ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) -{ - EphyrHostXVAdaptor *cur_host_adaptor=NULL ; - EphyrHostVideoFormat *video_formats=NULL ; - EphyrHostEncoding *encodings=NULL ; - EphyrHostAttribute *attributes=NULL ; - EphyrHostImageFormat *image_formats=NULL ; - int num_video_formats=0, base_port_id=0, - num_attributes=0, num_formats=0, i=0, - port_priv_offset=0; - unsigned num_encodings=0 ; - Bool is_ok = FALSE ; - - EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) { - EPHYR_LOG_ERROR ("failed to query host adaptors\n") ; - goto out ; - } - if (a_this->host_adaptors) - a_this->num_adaptors = - ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ; - if (a_this->num_adaptors < 0) { - EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ; - goto out ; - } - EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ; - /* - * copy what we can from adaptors into a_this->adaptors - */ - if (a_this->num_adaptors) { - a_this->adaptors = xcalloc (a_this->num_adaptors, - sizeof (KdVideoAdaptorRec)) ; - if (!a_this->adaptors) { - EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ; - goto out ; - } - } - for (i=0; i < a_this->num_adaptors; i++) { - int j=0 ; - cur_host_adaptor = - ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ; - if (!cur_host_adaptor) - continue ; - a_this->adaptors[i].nPorts = - ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ; - if (a_this->adaptors[i].nPorts <=0) { - EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ; - continue ; - } - a_this->adaptors[i].type = - ephyrHostXVAdaptorGetType (cur_host_adaptor) ; - a_this->adaptors[i].type |= XvWindowMask ; - a_this->adaptors[i].flags = - VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - if (ephyrHostXVAdaptorGetName (cur_host_adaptor)) - a_this->adaptors[i].name = - strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ; - else - a_this->adaptors[i].name = strdup ("Xephyr Video Overlay"); - base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ; - if (base_port_id < 0) { - EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ; - continue ; - } - if (!s_base_port_id) - s_base_port_id = base_port_id ; - - if (!ephyrHostXVQueryEncodings (base_port_id, - &encodings, - &num_encodings)) { - EPHYR_LOG_ERROR ("failed to get encodings for port port id %d," - " adaptors %d\n", - base_port_id, i) ; - continue ; - } - a_this->adaptors[i].nEncodings = num_encodings ; - a_this->adaptors[i].pEncodings = - videoEncodingDup (encodings, num_encodings) ; - video_formats = (EphyrHostVideoFormat*) - ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor, - &num_video_formats); - a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ; - a_this->adaptors[i].nFormats = num_video_formats ; - /* got a_this->adaptors[i].nPorts already - a_this->adaptors[i].nPorts = - ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ; - */ - a_this->adaptors[i].pPortPrivates = - xcalloc (a_this->adaptors[i].nPorts, - sizeof (DevUnion) + sizeof (EphyrPortPriv)) ; - port_priv_offset = a_this->adaptors[i].nPorts; - for (j=0; j < a_this->adaptors[i].nPorts; j++) { - EphyrPortPriv *port_privs_base = - (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset]; - EphyrPortPriv *port_priv = &port_privs_base[j] ; - port_priv->port_number = base_port_id + j; - port_priv->current_adaptor = &a_this->adaptors[i] ; - port_priv->xv_priv = a_this ; - a_this->adaptors[i].pPortPrivates[j].ptr = port_priv; - } - if (!ephyrHostXVQueryPortAttributes (base_port_id, - &attributes, - &num_attributes)) { - EPHYR_LOG_ERROR ("failed to get port attribute " - "for adaptor %d\n", i) ; - continue ; - } - a_this->adaptors[i].pAttributes = - portAttributesDup (attributes, num_attributes); - a_this->adaptors[i].nAttributes = num_attributes ; - /*make sure atoms of attrs names are created in xephyr*/ - for (j=0; j < a_this->adaptors[i].nAttributes; j++) { - if (a_this->adaptors[i].pAttributes[j].name) - MakeAtom (a_this->adaptors[i].pAttributes[j].name, - strlen (a_this->adaptors[i].pAttributes[j].name), - TRUE) ; - } - if (!ephyrHostXVQueryImageFormats (base_port_id, - &image_formats, - &num_formats)) { - EPHYR_LOG_ERROR ("failed to get image formats " - "for adaptor %d\n", i) ; - continue ; - } - a_this->adaptors[i].pImages = (KdImagePtr) image_formats ; - a_this->adaptors[i].nImages = num_formats ; - } - is_ok = TRUE ; - -out: - if (encodings) { - ephyrHostEncodingsDelete (encodings, num_encodings) ; - encodings = NULL ; - } - if (attributes) { - ephyrHostAttributesDelete (attributes) ; - attributes = NULL ; - } - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -static Bool -ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) -{ - int i=0 ; - Bool has_it=FALSE ; - EphyrHostXVAdaptor *cur_host_adaptor=NULL ; - - EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - for (i=0; i < a_this->num_adaptors; i++) { - a_this->adaptors[i].ReputImage = ephyrReputImage ; - a_this->adaptors[i].StopVideo = ephyrStopVideo ; - a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ; - a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ; - a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ; - a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ; - - cur_host_adaptor = - ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ; - if (!cur_host_adaptor) { - EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ; - continue ; - } - has_it = FALSE ; - if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) { - EPHYR_LOG_ERROR ("error\n") ; - } - if (has_it) { - a_this->adaptors[i].PutImage = ephyrPutImage; - } - - has_it = FALSE ; - if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) { - EPHYR_LOG_ERROR ("error\n") ; - } - if (has_it) { - a_this->adaptors[i].PutVideo = ephyrPutVideo; - } - - has_it = FALSE ; - if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) { - EPHYR_LOG_ERROR ("error\n") ; - } - if (has_it) { - a_this->adaptors[i].GetVideo = ephyrGetVideo; - } - - has_it = FALSE ; - if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) { - EPHYR_LOG_ERROR ("error\n") ; - } - if (has_it) { - a_this->adaptors[i].PutStill = ephyrPutStill; - } - - has_it = FALSE ; - if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) { - EPHYR_LOG_ERROR ("error\n") ; - } - if (has_it) { - a_this->adaptors[i].GetStill = ephyrGetStill; - } - } - EPHYR_LOG ("leave\n") ; - return TRUE ; -} - -static Bool -ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this, - ScreenPtr a_screen) -{ - KdScreenPriv(a_screen); - KdScreenInfo *screen = pScreenPriv->screen; - Bool is_ok = FALSE ; - KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ; - int num_registered_adaptors=0, i=0, num_adaptors=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - if (!a_this->num_adaptors) - goto out ; - num_registered_adaptors = - KdXVListGenericAdaptors (screen, ®istered_adaptors); - - num_adaptors = num_registered_adaptors + a_this->num_adaptors ; - adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ; - if (!adaptors) { - EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ; - goto out ; - } - memmove (adaptors, registered_adaptors, num_registered_adaptors) ; - for (i=0 ; i < a_this->num_adaptors; i++) { - *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ; - } - if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) { - EPHYR_LOG_ERROR ("failed to register adaptors\n"); - goto out ; - } - EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ; - is_ok = TRUE ; - -out: - xfree (registered_adaptors) ; - registered_adaptors = NULL ; - xfree (adaptors) ; - adaptors = NULL ; - - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -static Bool -ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs, - int a_attrs_len, - const char *a_attr_name, - int a_attr_value, - Bool *a_is_valid) -{ - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid, - FALSE) ; - - for (i=0; i < a_attrs_len; i++) { - if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name)) - continue ; - if (a_attrs[i].min_value > a_attr_value || - a_attrs[i].max_value < a_attr_value) { - *a_is_valid = FALSE ; - EPHYR_LOG_ERROR ("attribute was not valid\n" - "value:%d. min:%d. max:%d\n", - a_attr_value, - a_attrs[i].min_value, - a_attrs[i].max_value) ; - } else { - *a_is_valid = TRUE ; - } - return TRUE ; - } - return FALSE ; -} - -static Bool -ephyrXVPrivGetImageBufSize (int a_port_id, - int a_image_id, - unsigned short a_width, - unsigned short a_height, - int *a_size) -{ - Bool is_ok=FALSE ; - unsigned short width=a_width, height=a_height ; - - EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id, - &width, &height, a_size, NULL, NULL)) { - EPHYR_LOG_ERROR ("failed to get image attributes\n") ; - goto out ; - } - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -static Bool -ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv, - const unsigned char *a_image_buf, - int a_image_len) -{ - Bool is_ok=FALSE ; - - EPHYR_LOG ("enter\n") ; - - if (a_port_priv->image_buf_size < a_image_len) { - unsigned char *buf=NULL ; - buf = realloc (a_port_priv->image_buf, a_image_len) ; - if (!buf) { - EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ; - goto out ; - } - a_port_priv->image_buf = buf ; - a_port_priv->image_buf_size = a_image_len; - } - memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ; - is_ok = TRUE ; - -out: - return is_ok ; - EPHYR_LOG ("leave\n") ; -} - -static void -ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit) -{ - EphyrPortPriv *port_priv = a_port_priv ; - - EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ; - EPHYR_RETURN_IF_FAIL (port_priv) ; - - EPHYR_LOG ("enter\n") ; - if (!ephyrHostXVStopVideo (a_info->pScreen->myNum, - port_priv->port_number)) { - EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ; - } - EPHYR_LOG ("leave\n") ; -} - -static int -ephyrSetPortAttribute (KdScreenInfo *a_info, - Atom a_attr_name, - int a_attr_value, - pointer a_port_priv) -{ - int res=Success, host_atom=0 ; - EphyrPortPriv *port_priv = a_port_priv ; - Bool is_attr_valid=FALSE ; - - EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ; - EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ; - EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes, - BadMatch) ; - EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes, - BadMatch) ; - EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ; - - EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n", - port_priv->port_number, - (int)a_attr_name, - NameForAtom (a_attr_name), - a_attr_value) ; - - if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) { - EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ; - res = BadMatch ; - goto out ; - } - - if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes, - port_priv->current_adaptor->nAttributes, - NameForAtom (a_attr_name), - a_attr_value, - &is_attr_valid)) { - EPHYR_LOG_ERROR ("failed to validate attribute %s\n", - NameForAtom (a_attr_name)) ; - /* - res = BadMatch ; - goto out ; - */ - } - if (!is_attr_valid) { - EPHYR_LOG_ERROR ("attribute %s is not valid\n", - NameForAtom (a_attr_name)) ; - /* - res = BadMatch ; - goto out ; - */ - } - - if (!ephyrHostXVSetPortAttribute (port_priv->port_number, - host_atom, - a_attr_value)) { - EPHYR_LOG_ERROR ("failed to set port attribute\n") ; - res = BadMatch ; - goto out ; - } - - res = Success ; -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -static int -ephyrGetPortAttribute (KdScreenInfo *a_screen_info, - Atom a_attr_name, - int *a_attr_value, - pointer a_port_priv) -{ - int res=Success, host_atom=0 ; - EphyrPortPriv *port_priv = a_port_priv ; - - EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ; - EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ; - - EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n", - port_priv->port_number, - (int)a_attr_name, - NameForAtom (a_attr_name)) ; - - if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) { - EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ; - res = BadMatch ; - goto out ; - } - - if (!ephyrHostXVGetPortAttribute (port_priv->port_number, - host_atom, - a_attr_value)) { - EPHYR_LOG_ERROR ("failed to get port attribute\n") ; - res = BadMatch ; - goto out ; - } - - res = Success ; -out: - EPHYR_LOG ("leave\n") ; - return res ; -} - -static void -ephyrQueryBestSize (KdScreenInfo *a_info, - Bool a_motion, - short a_src_w, - short a_src_h, - short a_drw_w, - short a_drw_h, - unsigned int *a_prefered_w, - unsigned int *a_prefered_h, - pointer a_port_priv) -{ - int res=0 ; - EphyrPortPriv *port_priv = a_port_priv ; - - EPHYR_RETURN_IF_FAIL (port_priv) ; - - EPHYR_LOG ("enter\n") ; - res = ephyrHostXVQueryBestSize (port_priv->port_number, - a_motion, - a_src_w, a_src_h, - a_drw_w, a_drw_h, - a_prefered_w, a_prefered_h) ; - if (!res) { - EPHYR_LOG_ERROR ("Failed to query best size\n") ; - } - EPHYR_LOG ("leave\n") ; -} - -static int -ephyrPutImage (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_src_x, - short a_src_y, - short a_drw_x, - short a_drw_y, - short a_src_w, - short a_src_h, - short a_drw_w, - short a_drw_h, - int a_id, - unsigned char *a_buf, - short a_width, - short a_height, - Bool a_sync, - RegionPtr a_clipping_region, - pointer a_port_priv) -{ - EphyrPortPriv *port_priv = a_port_priv ; - Bool is_ok=FALSE ; - int result=BadImplementation, image_size=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; - EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ; - - EPHYR_LOG ("enter\n") ; - - if (!ephyrHostXVPutImage (a_info->pScreen->myNum, - port_priv->port_number, - a_id, - a_drw_x, a_drw_y, a_drw_w, a_drw_h, - a_src_x, a_src_y, a_src_w, a_src_h, - a_width, a_height, a_buf, - (EphyrHostBox*)REGION_RECTS (a_clipping_region), - REGION_NUM_RECTS (a_clipping_region))) { - EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ; - goto out ; - } - - /* - * Now save the image so that we can resend it to host it - * later, in ReputImage. - */ - if (!ephyrXVPrivGetImageBufSize (port_priv->port_number, - a_id, a_width, a_height, &image_size)) { - EPHYR_LOG_ERROR ("failed to get image size\n") ; - /*this is a minor error so we won't get bail out abruptly*/ - is_ok = FALSE ; - } else { - is_ok = TRUE ; - } - if (is_ok) { - if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) { - is_ok=FALSE ; - } else { - port_priv->image_id = a_id; - port_priv->drw_x = a_drw_x; - port_priv->drw_y = a_drw_y; - port_priv->drw_w = a_drw_w ; - port_priv->drw_h = a_drw_h ; - port_priv->src_x = a_src_x; - port_priv->src_y = a_src_y ; - port_priv->src_w = a_src_w ; - port_priv->src_h = a_src_h ; - port_priv->image_width = a_width ; - port_priv->image_height = a_height ; - } - } - if (!is_ok) { - if (port_priv->image_buf) { - free (port_priv->image_buf) ; - port_priv->image_buf = NULL ; - port_priv->image_buf_size = 0 ; - } - } - - result = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return result ; -} - -static int -ephyrReputImage (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_drw_x, - short a_drw_y, - RegionPtr a_clipping_region, - pointer a_port_priv) -{ - EphyrPortPriv *port_priv = a_port_priv ; - int result=BadImplementation ; - - EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ; - EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; - - EPHYR_LOG ("enter\n") ; - - if (!port_priv->image_buf_size || !port_priv->image_buf) { - EPHYR_LOG_ERROR ("has null image buf in cache\n") ; - goto out ; - } - if (!ephyrHostXVPutImage (a_info->pScreen->myNum, - port_priv->port_number, - port_priv->image_id, - a_drw_x, a_drw_y, - port_priv->drw_w, port_priv->drw_h, - port_priv->src_x, port_priv->src_y, - port_priv->src_w, port_priv->src_h, - port_priv->image_width, port_priv->image_height, - port_priv->image_buf, - (EphyrHostBox*)REGION_RECTS (a_clipping_region), - REGION_NUM_RECTS (a_clipping_region))) { - EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ; - goto out ; - } - - result = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return result ; -} - -static int -ephyrPutVideo (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clipping_region, - pointer a_port_priv) -{ - EphyrPortPriv *port_priv = a_port_priv ; - BoxRec clipped_area, dst_box ; - int result=BadImplementation ; - int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ; - EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; - - EPHYR_LOG ("enter\n") ; - - dst_box.x1 = a_drw_x ; - dst_box.x2 = a_drw_x + a_drw_w; - dst_box.y1 = a_drw_y ; - dst_box.y2 = a_drw_y + a_drw_h; - - if (!DoSimpleClip (&dst_box, - REGION_EXTENTS (pScreen->pScreen, a_clipping_region), - &clipped_area)) { - EPHYR_LOG_ERROR ("failed to simple clip\n") ; - goto out ; - } - - drw_x = clipped_area.x1 ; - drw_y = clipped_area.y1 ; - drw_w = clipped_area.x2 - clipped_area.x1 ; - drw_h = clipped_area.y2 - clipped_area.y1 ; - - if (!ephyrHostXVPutVideo (a_info->pScreen->myNum, - port_priv->port_number, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { - EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ; - goto out ; - } - result = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return result ; -} - -static int -ephyrGetVideo (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clipping_region, - pointer a_port_priv) -{ - EphyrPortPriv *port_priv = a_port_priv ; - BoxRec clipped_area, dst_box ; - int result=BadImplementation ; - int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; - EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; - - EPHYR_LOG ("enter\n") ; - - dst_box.x1 = a_drw_x ; - dst_box.x2 = a_drw_x + a_drw_w; - dst_box.y1 = a_drw_y ; - dst_box.y2 = a_drw_y + a_drw_h; - - if (!DoSimpleClip (&dst_box, - REGION_EXTENTS (pScreen->pScreen, a_clipping_region), - &clipped_area)) { - EPHYR_LOG_ERROR ("failed to simple clip\n") ; - goto out ; - } - - drw_x = clipped_area.x1 ; - drw_y = clipped_area.y1 ; - drw_w = clipped_area.x2 - clipped_area.x1 ; - drw_h = clipped_area.y2 - clipped_area.y1 ; - - if (!ephyrHostXVGetVideo (a_info->pScreen->myNum, - port_priv->port_number, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { - EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ; - goto out ; - } - result = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return result ; -} - -static int -ephyrPutStill (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clipping_region, - pointer a_port_priv) -{ - EphyrPortPriv *port_priv = a_port_priv ; - BoxRec clipped_area, dst_box ; - int result=BadImplementation ; - int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; - EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; - - EPHYR_LOG ("enter\n") ; - - dst_box.x1 = a_drw_x ; - dst_box.x2 = a_drw_x + a_drw_w; - dst_box.y1 = a_drw_y ; - dst_box.y2 = a_drw_y + a_drw_h; - - if (!DoSimpleClip (&dst_box, - REGION_EXTENTS (pScreen->pScreen, a_clipping_region), - &clipped_area)) { - EPHYR_LOG_ERROR ("failed to simple clip\n") ; - goto out ; - } - - drw_x = clipped_area.x1 ; - drw_y = clipped_area.y1 ; - drw_w = clipped_area.x2 - clipped_area.x1 ; - drw_h = clipped_area.y2 - clipped_area.y1 ; - - if (!ephyrHostXVPutStill (a_info->pScreen->myNum, - port_priv->port_number, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { - EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ; - goto out ; - } - result = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return result ; -} - -static int -ephyrGetStill (KdScreenInfo *a_info, - DrawablePtr a_drawable, - short a_vid_x, short a_vid_y, - short a_drw_x, short a_drw_y, - short a_vid_w, short a_vid_h, - short a_drw_w, short a_drw_h, - RegionPtr a_clipping_region, - pointer a_port_priv) -{ - EphyrPortPriv *port_priv = a_port_priv ; - BoxRec clipped_area, dst_box ; - int result=BadImplementation ; - int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; - EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; - - EPHYR_LOG ("enter\n") ; - - dst_box.x1 = a_drw_x ; - dst_box.x2 = a_drw_x + a_drw_w; - dst_box.y1 = a_drw_y ; - dst_box.y2 = a_drw_y + a_drw_h; - - if (!DoSimpleClip (&dst_box, - REGION_EXTENTS (pScreen->pScreen, a_clipping_region), - &clipped_area)) { - EPHYR_LOG_ERROR ("failed to simple clip\n") ; - goto out ; - } - - drw_x = clipped_area.x1 ; - drw_y = clipped_area.y1 ; - drw_w = clipped_area.x2 - clipped_area.x1 ; - drw_h = clipped_area.y2 - clipped_area.y1 ; - - if (!ephyrHostXVGetStill (a_info->pScreen->myNum, - port_priv->port_number, - a_vid_x, a_vid_y, a_vid_w, a_vid_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { - EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ; - goto out ; - } - result = Success ; - -out: - EPHYR_LOG ("leave\n") ; - return result ; -} - -static int -ephyrQueryImageAttributes (KdScreenInfo *a_info, - int a_id, - unsigned short *a_w, - unsigned short *a_h, - int *a_pitches, - int *a_offsets) -{ - int image_size=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ; - - EPHYR_LOG ("enter: dim (%dx%d), pitches: %p, offsets: %p\n", - *a_w, *a_h, a_pitches, a_offsets) ; - - if (!ephyrHostXVQueryImageAttributes (s_base_port_id, - a_id, - a_w, a_h, - &image_size, - a_pitches, a_offsets)) { - EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ; - goto out ; - } - EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ; - -out: - EPHYR_LOG ("leave\n") ; - return image_size ; -} +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include <string.h>
+#include <X11/extensions/Xv.h>
+#include "ephyrlog.h"
+#include "kdrive.h"
+#include "kxv.h"
+#include "ephyr.h"
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+
+struct _EphyrXVPriv {
+ EphyrHostXVAdaptorArray *host_adaptors ;
+ KdVideoAdaptorPtr adaptors ;
+ int num_adaptors ;
+};
+typedef struct _EphyrXVPriv EphyrXVPriv ;
+
+struct _EphyrPortPriv {
+ int port_number ;
+ KdVideoAdaptorPtr current_adaptor ;
+ EphyrXVPriv *xv_priv;
+ unsigned char *image_buf ;
+ int image_buf_size ;
+ int image_id ;
+ int drw_x, drw_y, drw_w, drw_h ;
+ int src_x, src_y, src_w, src_h ;
+ int image_width, image_height ;
+};
+typedef struct _EphyrPortPriv EphyrPortPriv ;
+
+static Bool DoSimpleClip (BoxPtr a_dst_drw,
+ BoxPtr a_clipper,
+ BoxPtr a_result) ;
+
+static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
+
+/*
+static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
+*/
+
+static EphyrXVPriv* ephyrXVPrivNew (void) ;
+static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen) ;
+
+static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid) ;
+
+static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size) ;
+
+static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image,
+ int a_image_len) ;
+
+static void ephyrStopVideo (KdScreenInfo *a_info,
+ pointer a_xv_priv,
+ Bool a_exit);
+
+static int ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv);
+
+static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv);
+
+static void ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv);
+
+static int ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv);
+
+static int ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets);
+static int s_base_port_id ;
+
+/**************
+ * <helpers>
+ * ************/
+
+static Bool
+DoSimpleClip (BoxPtr a_dst_box,
+ BoxPtr a_clipper,
+ BoxPtr a_result)
+{
+ BoxRec dstClippedBox ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
+
+ /*
+ * setup the clipbox inside the destination.
+ */
+ dstClippedBox.x1 = a_dst_box->x1 ;
+ dstClippedBox.x2 = a_dst_box->x2 ;
+ dstClippedBox.y1 = a_dst_box->y1 ;
+ dstClippedBox.y2 = a_dst_box->y2 ;
+
+ /*
+ * if the cliper leftmost edge is inside
+ * the destination area then the leftmost edge of the resulting
+ * clipped box is the leftmost edge of the cliper.
+ */
+ if (a_clipper->x1 > dstClippedBox.x1)
+ dstClippedBox.x1 = a_clipper->x1 ;
+
+ /*
+ * if the cliper top edge is inside the destination area
+ * then the bottom horizontal edge of the resulting clipped box
+ * is the bottom edge of the cliper
+ */
+ if (a_clipper->y1 > dstClippedBox.y1)
+ dstClippedBox.y1 = a_clipper->y1 ;
+
+ /*ditto for right edge*/
+ if (a_clipper->x2 < dstClippedBox.x2)
+ dstClippedBox.x2 = a_clipper->x2 ;
+
+ /*ditto for bottom edge*/
+ if (a_clipper->y2 < dstClippedBox.y2)
+ dstClippedBox.y2 = a_clipper->y2 ;
+
+ memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
+ return TRUE ;
+}
+
+static Bool
+ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
+{
+ const char *atom_name=NULL;
+ int host_atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
+
+ if (!ValidAtom (a_local_atom))
+ return FALSE ;
+
+ atom_name = NameForAtom (a_local_atom) ;
+
+ if (!atom_name)
+ return FALSE ;
+
+ if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
+ EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
+ atom_name) ;
+ return FALSE ;
+ }
+ *a_host_atom = host_atom ;
+ return TRUE ;
+}
+
+/*
+ Not used yed.
+static Bool
+ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
+{
+ Bool is_ok=FALSE ;
+ char *atom_name=NULL ;
+ int atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
+
+ atom_name = ephyrHostGetAtomName (a_host_atom) ;
+ if (!atom_name)
+ goto out ;
+
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
+ if (atom == None)
+ goto out ;
+
+ *a_local_atom = atom ;
+ is_ok = TRUE ;
+
+out:
+ if (atom_name) {
+ ephyrHostFree (atom_name) ;
+ }
+ return is_ok ;
+}
+*/
+
+/**************
+ *</helpers>
+ * ************/
+
+Bool
+ephyrInitVideo (ScreenPtr pScreen)
+{
+ Bool is_ok = FALSE ;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ static EphyrXVPriv *xv_priv;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (screen->fb.bitsPerPixel == 8) {
+ EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
+ return FALSE ;
+ }
+
+ if (!xv_priv) {
+ xv_priv = ephyrXVPrivNew () ;
+ }
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+}
+
+static EphyrXVPriv*
+ephyrXVPrivNew (void)
+{
+ EphyrXVPriv *xv_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ xv_priv = calloc(1, sizeof (EphyrXVPriv)) ;
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
+ goto error ;
+ }
+
+ ephyrHostXVInit () ;
+
+ if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
+ goto error ;
+ }
+ if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
+ goto error ;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return xv_priv ;
+
+error:
+ if (xv_priv) {
+ ephyrXVPrivDelete (xv_priv) ;
+ xv_priv = NULL ;
+ }
+ return NULL ;
+}
+
+static void
+ephyrXVPrivDelete (EphyrXVPriv *a_this)
+{
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this)
+ return ;
+ if (a_this->host_adaptors) {
+ ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
+ a_this->host_adaptors = NULL ;
+ }
+ free(a_this->adaptors) ;
+ a_this->adaptors = NULL ;
+ free(a_this) ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static KdVideoEncodingPtr
+videoEncodingDup (EphyrHostEncoding *a_encodings,
+ int a_num_encodings)
+{
+ KdVideoEncodingPtr result = NULL ;
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = calloc(a_num_encodings, sizeof (KdVideoEncodingRec)) ;
+ for (i=0 ; i < a_num_encodings; i++) {
+ result[i].id = a_encodings[i].id ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ result[i].width = a_encodings[i].width ;
+ result[i].height = a_encodings[i].height ;
+ result[i].rate.numerator = a_encodings[i].rate.numerator ;
+ result[i].rate.denominator = a_encodings[i].rate.denominator ;
+ }
+ return result ;
+}
+
+static KdAttributePtr
+portAttributesDup (EphyrHostAttribute *a_encodings,
+ int a_num_encodings)
+{
+ int i=0 ;
+ KdAttributePtr result=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = calloc(a_num_encodings, sizeof (KdAttributeRec)) ;
+ if (!result) {
+ EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
+ return NULL ;
+ }
+ for (i=0; i < a_num_encodings; i++) {
+ result[i].flags = a_encodings[i].flags ;
+ result[i].min_value = a_encodings[i].min_value ;
+ result[i].max_value = a_encodings[i].max_value ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ }
+ return result ;
+}
+
+static Bool
+ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
+{
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+ EphyrHostVideoFormat *video_formats=NULL ;
+ EphyrHostEncoding *encodings=NULL ;
+ EphyrHostAttribute *attributes=NULL ;
+ EphyrHostImageFormat *image_formats=NULL ;
+ int num_video_formats=0, base_port_id=0,
+ num_attributes=0, num_formats=0, i=0,
+ port_priv_offset=0;
+ unsigned num_encodings=0 ;
+ Bool is_ok = FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
+ goto out ;
+ }
+ if (a_this->host_adaptors)
+ a_this->num_adaptors =
+ ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+ if (a_this->num_adaptors < 0) {
+ EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
+ /*
+ * copy what we can from adaptors into a_this->adaptors
+ */
+ if (a_this->num_adaptors) {
+ a_this->adaptors = calloc(a_this->num_adaptors,
+ sizeof (KdVideoAdaptorRec)) ;
+ if (!a_this->adaptors) {
+ EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
+ goto out ;
+ }
+ }
+ for (i=0; i < a_this->num_adaptors; i++) {
+ int j=0 ;
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor)
+ continue ;
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ if (a_this->adaptors[i].nPorts <=0) {
+ EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].type =
+ ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
+ a_this->adaptors[i].type |= XvWindowMask ;
+ a_this->adaptors[i].flags =
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
+ a_this->adaptors[i].name =
+ strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
+ else
+ a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
+ base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
+ if (base_port_id < 0) {
+ EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
+ continue ;
+ }
+ if (!s_base_port_id)
+ s_base_port_id = base_port_id ;
+
+ if (!ephyrHostXVQueryEncodings (base_port_id,
+ &encodings,
+ &num_encodings)) {
+ EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
+ " adaptors %d\n",
+ base_port_id, i) ;
+ continue ;
+ }
+ a_this->adaptors[i].nEncodings = num_encodings ;
+ a_this->adaptors[i].pEncodings =
+ videoEncodingDup (encodings, num_encodings) ;
+ video_formats = (EphyrHostVideoFormat*)
+ ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
+ &num_video_formats);
+ a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
+ a_this->adaptors[i].nFormats = num_video_formats ;
+ /* got a_this->adaptors[i].nPorts already
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ */
+ a_this->adaptors[i].pPortPrivates =
+ calloc(a_this->adaptors[i].nPorts,
+ sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
+ port_priv_offset = a_this->adaptors[i].nPorts;
+ for (j=0; j < a_this->adaptors[i].nPorts; j++) {
+ EphyrPortPriv *port_privs_base =
+ (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
+ EphyrPortPriv *port_priv = &port_privs_base[j] ;
+ port_priv->port_number = base_port_id + j;
+ port_priv->current_adaptor = &a_this->adaptors[i] ;
+ port_priv->xv_priv = a_this ;
+ a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
+ }
+ if (!ephyrHostXVQueryPortAttributes (base_port_id,
+ &attributes,
+ &num_attributes)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pAttributes =
+ portAttributesDup (attributes, num_attributes);
+ a_this->adaptors[i].nAttributes = num_attributes ;
+ /*make sure atoms of attrs names are created in xephyr*/
+ for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
+ if (a_this->adaptors[i].pAttributes[j].name)
+ MakeAtom (a_this->adaptors[i].pAttributes[j].name,
+ strlen (a_this->adaptors[i].pAttributes[j].name),
+ TRUE) ;
+ }
+ if (!ephyrHostXVQueryImageFormats (base_port_id,
+ &image_formats,
+ &num_formats)) {
+ EPHYR_LOG_ERROR ("failed to get image formats "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
+ a_this->adaptors[i].nImages = num_formats ;
+ }
+ is_ok = TRUE ;
+
+out:
+ if (encodings) {
+ ephyrHostEncodingsDelete (encodings, num_encodings) ;
+ encodings = NULL ;
+ }
+ if (attributes) {
+ ephyrHostAttributesDelete (attributes) ;
+ attributes = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
+{
+ int i=0 ;
+ Bool has_it=FALSE ;
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ for (i=0; i < a_this->num_adaptors; i++) {
+ a_this->adaptors[i].ReputImage = ephyrReputImage ;
+ a_this->adaptors[i].StopVideo = ephyrStopVideo ;
+ a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
+ a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
+ a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
+ a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
+
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor) {
+ EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
+ continue ;
+ }
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutImage = ephyrPutImage;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutVideo = ephyrPutVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetVideo = ephyrGetVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutStill = ephyrPutStill;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetStill = ephyrGetStill;
+ }
+ }
+ EPHYR_LOG ("leave\n") ;
+ return TRUE ;
+}
+
+static Bool
+ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen)
+{
+ KdScreenPriv(a_screen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ Bool is_ok = FALSE ;
+ KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
+ int num_registered_adaptors=0, i=0, num_adaptors=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this->num_adaptors)
+ goto out ;
+ num_registered_adaptors =
+ KdXVListGenericAdaptors (screen, ®istered_adaptors);
+
+ num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
+ adaptors = calloc(num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
+ if (!adaptors) {
+ EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
+ goto out ;
+ }
+ memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
+ for (i=0 ; i < a_this->num_adaptors; i++) {
+ *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
+ }
+ if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n");
+ goto out ;
+ }
+ EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ;
+ is_ok = TRUE ;
+
+out:
+ free(registered_adaptors) ;
+ registered_adaptors = NULL ;
+ free(adaptors) ;
+ adaptors = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
+ FALSE) ;
+
+ for (i=0; i < a_attrs_len; i++) {
+ if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
+ continue ;
+ if (a_attrs[i].min_value > a_attr_value ||
+ a_attrs[i].max_value < a_attr_value) {
+ *a_is_valid = FALSE ;
+ EPHYR_LOG_ERROR ("attribute was not valid\n"
+ "value:%d. min:%d. max:%d\n",
+ a_attr_value,
+ a_attrs[i].min_value,
+ a_attrs[i].max_value) ;
+ } else {
+ *a_is_valid = TRUE ;
+ }
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+static Bool
+ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size)
+{
+ Bool is_ok=FALSE ;
+ unsigned short width=a_width, height=a_height ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
+ &width, &height, a_size, NULL, NULL)) {
+ EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image_buf,
+ int a_image_len)
+{
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_port_priv->image_buf_size < a_image_len) {
+ unsigned char *buf=NULL ;
+ buf = realloc (a_port_priv->image_buf, a_image_len) ;
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
+ goto out ;
+ }
+ a_port_priv->image_buf = buf ;
+ a_port_priv->image_buf_size = a_image_len;
+ }
+ memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static void
+ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
+ port_priv->port_number)) {
+ EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_attr_valid=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name),
+ a_attr_value) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
+ port_priv->current_adaptor->nAttributes,
+ NameForAtom (a_attr_name),
+ a_attr_value,
+ &is_attr_valid)) {
+ EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+ if (!is_attr_valid) {
+ EPHYR_LOG_ERROR ("attribute %s is not valid\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+
+ if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static int
+ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name)) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static void
+ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv)
+{
+ int res=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ res = ephyrHostXVQueryBestSize (port_priv->port_number,
+ a_motion,
+ a_src_w, a_src_h,
+ a_drw_w, a_drw_h,
+ a_prefered_w, a_prefered_h) ;
+ if (!res) {
+ EPHYR_LOG_ERROR ("Failed to query best size\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_ok=FALSE ;
+ int result=BadImplementation, image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_id,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_width, a_height, a_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ /*
+ * Now save the image so that we can resend it to host it
+ * later, in ReputImage.
+ */
+ if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
+ a_id, a_width, a_height, &image_size)) {
+ EPHYR_LOG_ERROR ("failed to get image size\n") ;
+ /*this is a minor error so we won't get bail out abruptly*/
+ is_ok = FALSE ;
+ } else {
+ is_ok = TRUE ;
+ }
+ if (is_ok) {
+ if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
+ is_ok=FALSE ;
+ } else {
+ port_priv->image_id = a_id;
+ port_priv->drw_x = a_drw_x;
+ port_priv->drw_y = a_drw_y;
+ port_priv->drw_w = a_drw_w ;
+ port_priv->drw_h = a_drw_h ;
+ port_priv->src_x = a_src_x;
+ port_priv->src_y = a_src_y ;
+ port_priv->src_w = a_src_w ;
+ port_priv->src_h = a_src_h ;
+ port_priv->image_width = a_width ;
+ port_priv->image_height = a_height ;
+ }
+ }
+ if (!is_ok) {
+ if (port_priv->image_buf) {
+ free (port_priv->image_buf) ;
+ port_priv->image_buf = NULL ;
+ port_priv->image_buf_size = 0 ;
+ }
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ int result=BadImplementation ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!port_priv->image_buf_size || !port_priv->image_buf) {
+ EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
+ goto out ;
+ }
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ port_priv->image_id,
+ a_drw_x, a_drw_y,
+ port_priv->drw_w, port_priv->drw_h,
+ port_priv->src_x, port_priv->src_y,
+ port_priv->src_w, port_priv->src_h,
+ port_priv->image_width, port_priv->image_height,
+ port_priv->image_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets)
+{
+ int image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
+
+ EPHYR_LOG ("enter: dim (%dx%d), pitches: %p, offsets: %p\n",
+ *a_w, *a_h, a_pitches, a_offsets) ;
+
+ if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
+ a_id,
+ a_w, a_h,
+ &image_size,
+ a_pitches, a_offsets)) {
+ EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return image_size ;
+}
|