aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/ephyr
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2010-05-15 16:28:11 +0000
committermarha <marha@users.sourceforge.net>2010-05-15 16:28:11 +0000
commitc38dead3ea7e177728d90cd815cf4eead0c9f534 (patch)
treeb809dba1dc9013bb1e67a5ee388f2dd217dc0f88 /xorg-server/hw/kdrive/ephyr
parent6083a94d68878c9ad5f59b28bd07e4738e9fb7b4 (diff)
downloadvcxsrv-c38dead3ea7e177728d90cd815cf4eead0c9f534.tar.gz
vcxsrv-c38dead3ea7e177728d90cd815cf4eead0c9f534.tar.bz2
vcxsrv-c38dead3ea7e177728d90cd815cf4eead0c9f534.zip
xserver git update 15/5/2010
Diffstat (limited to 'xorg-server/hw/kdrive/ephyr')
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c2358
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_draw.c1047
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrdriext.c2858
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrglxext.c1446
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c2024
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrvideo.c2546
6 files changed, 6139 insertions, 6140 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
index b21559bba..439a2b274 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -1,1179 +1,1179 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- * Authored by Matthew Allum <mallum@openedhand.com>
- *
- * Copyright © 2004 Nokia
- *
- * 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 Nokia not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Nokia makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL NOKIA 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "ephyr.h"
-
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "ephyrlog.h"
-
-#ifdef XF86DRI
-#include "ephyrdri.h"
-#include "ephyrdriext.h"
-#include "ephyrglxext.h"
-#endif /* XF86DRI */
-
-extern int KdTsPhyScreen;
-#ifdef GLXEXT
-extern Bool noGlxVisualInit;
-#endif
-
-KdKeyboardInfo *ephyrKbd;
-KdPointerInfo *ephyrMouse;
-EphyrKeySyms ephyrKeySyms;
-Bool ephyrNoDRI=FALSE ;
-Bool ephyrNoXV=FALSE ;
-
-static int mouseState = 0;
-
-typedef struct _EphyrInputPrivate {
- Bool enabled;
-} EphyrKbdPrivate, EphyrPointerPrivate;
-
-Bool EphyrWantGrayScale = 0;
-
-
-Bool
-ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
-{
- OsSignal(SIGUSR1, hostx_handle_signal);
-
- priv->base = 0;
- priv->bytes_per_line = 0;
- return TRUE;
-}
-
-Bool
-ephyrCardInit (KdCardInfo *card)
-{
- EphyrPriv *priv;
-
- priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv));
- if (!priv)
- return FALSE;
-
- if (!ephyrInitialize (card, priv))
- {
- xfree (priv);
- return FALSE;
- }
- card->driver = priv;
-
- return TRUE;
-}
-
-Bool
-ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
-{
- int width = 640, height = 480;
- CARD32 redMask, greenMask, blueMask;
-
- if (hostx_want_screen_size(screen, &width, &height)
- || !screen->width || !screen->height)
- {
- screen->width = width;
- screen->height = height;
- }
-
- if (EphyrWantGrayScale)
- screen->fb.depth = 8;
-
- if (screen->fb.depth && screen->fb.depth != hostx_get_depth())
- {
- if (screen->fb.depth < hostx_get_depth()
- && (screen->fb.depth == 24 || screen->fb.depth == 16
- || screen->fb.depth == 8))
- {
- hostx_set_server_depth(screen, screen->fb.depth);
- }
- else
- ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
- }
-
- screen->fb.depth = hostx_get_server_depth(screen);
- screen->rate = 72;
-
- if (screen->fb.depth <= 8)
- {
- if (EphyrWantGrayScale)
- screen->fb.visuals = ((1 << StaticGray) | (1 << GrayScale));
- else
- screen->fb.visuals = ((1 << StaticGray) |
- (1 << GrayScale) |
- (1 << StaticColor) |
- (1 << PseudoColor) |
- (1 << TrueColor) |
- (1 << DirectColor));
-
- screen->fb.redMask = 0x00;
- screen->fb.greenMask = 0x00;
- screen->fb.blueMask = 0x00;
- screen->fb.depth = 8;
- screen->fb.bitsPerPixel = 8;
- }
- else
- {
- screen->fb.visuals = (1 << TrueColor);
-
- if (screen->fb.depth <= 15)
- {
- screen->fb.depth = 15;
- screen->fb.bitsPerPixel = 16;
- }
- else if (screen->fb.depth <= 16)
- {
- screen->fb.depth = 16;
- screen->fb.bitsPerPixel = 16;
- }
- else if (screen->fb.depth <= 24)
- {
- screen->fb.depth = 24;
- screen->fb.bitsPerPixel = 32;
- }
- else if (screen->fb.depth <= 30)
- {
- screen->fb.depth = 30;
- screen->fb.bitsPerPixel = 32;
- }
- else
- {
- ErrorF("\nXephyr: Unsupported screen depth %d\n",
- screen->fb.depth);
- return FALSE;
- }
-
- hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
-
- screen->fb.redMask = (Pixel) redMask;
- screen->fb.greenMask = (Pixel) greenMask;
- screen->fb.blueMask = (Pixel) blueMask;
-
- }
-
- scrpriv->randr = screen->randr;
-
- return ephyrMapFramebuffer (screen);
-}
-
-Bool
-ephyrScreenInit (KdScreenInfo *screen)
-{
- EphyrScrPriv *scrpriv;
-
- scrpriv = xcalloc (1, sizeof (EphyrScrPriv));
-
- if (!scrpriv)
- return FALSE;
-
- screen->driver = scrpriv;
-
- if (!ephyrScreenInitialize (screen, scrpriv))
- {
- screen->driver = 0;
- xfree (scrpriv);
- return FALSE;
- }
-
- return TRUE;
-}
-
-void*
-ephyrWindowLinear (ScreenPtr pScreen,
- CARD32 row,
- CARD32 offset,
- int mode,
- CARD32 *size,
- void *closure)
-{
- KdScreenPriv(pScreen);
- EphyrPriv *priv = pScreenPriv->card->driver;
-
- if (!pScreenPriv->enabled)
- return 0;
-
- *size = priv->bytes_per_line;
- return priv->base + row * priv->bytes_per_line + offset;
-}
-
-/**
- * Figure out display buffer size. If fakexa is enabled, allocate a larger
- * buffer so that fakexa has space to put offscreen pixmaps.
- */
-int
-ephyrBufferHeight(KdScreenInfo *screen)
-{
- int buffer_height;
- if (ephyrFuncs.initAccel == NULL)
- buffer_height = screen->height;
- else
- buffer_height = 3 * screen->height;
- return buffer_height;
-}
-
-
-Bool
-ephyrMapFramebuffer (KdScreenInfo *screen)
-{
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrPriv *priv = screen->card->driver;
- KdPointerMatrix m;
- int buffer_height;
-
- EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
- screen->width, screen->height, screen->mynum);
-
- KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
- KdSetPointerMatrix (&m);
-
- priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
-
- buffer_height = ephyrBufferHeight(screen);
-
- priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
-
- if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All))
- {
- scrpriv->shadow = FALSE;
-
- screen->fb.byteStride = priv->bytes_per_line;
- screen->fb.pixelStride = screen->width;
- screen->fb.frameBuffer = (CARD8 *) (priv->base);
- }
- else
- {
- /* Rotated/Reflected so we need to use shadow fb */
- scrpriv->shadow = TRUE;
-
- EPHYR_LOG("allocing shadow");
-
- KdShadowFbAlloc (screen,
- scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
- }
-
- return TRUE;
-}
-
-void
-ephyrSetScreenSizes (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
-
- if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
- {
- pScreen->width = screen->width;
- pScreen->height = screen->height;
- pScreen->mmWidth = screen->width_mm;
- pScreen->mmHeight = screen->height_mm;
- }
- else
- {
- pScreen->width = screen->height;
- pScreen->height = screen->width;
- pScreen->mmWidth = screen->height_mm;
- pScreen->mmHeight = screen->width_mm;
- }
-}
-
-Bool
-ephyrUnmapFramebuffer (KdScreenInfo *screen)
-{
- EphyrScrPriv *scrpriv = screen->driver;
-
- if (scrpriv->shadow)
- KdShadowFbFree (screen);
-
- /* Note, priv->base will get freed when XImage recreated */
-
- return TRUE;
-}
-
-void
-ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
-
- EPHYR_LOG("slow paint");
-
- /* FIXME: Slow Rotated/Reflected updates could be much
- * much faster efficiently updating via tranforming
- * pBuf->pDamage regions
- */
- shadowUpdateRotatePacked(pScreen, pBuf);
- hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
-}
-
-static void
-ephyrInternalDamageRedisplay (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- RegionPtr pRegion;
-
- if (!scrpriv || !scrpriv->pDamage)
- return;
-
- pRegion = DamageRegion (scrpriv->pDamage);
-
- if (REGION_NOTEMPTY (pScreen, pRegion))
- {
- int nbox;
- BoxPtr pbox;
-
- nbox = REGION_NUM_RECTS (pRegion);
- pbox = REGION_RECTS (pRegion);
-
- while (nbox--)
- {
- hostx_paint_rect(screen,
- pbox->x1, pbox->y1,
- pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- pbox++;
- }
- DamageEmpty (scrpriv->pDamage);
- }
-}
-
-static void
-ephyrInternalDamageBlockHandler (pointer data,
- OSTimePtr pTimeout,
- pointer pRead)
-{
- ScreenPtr pScreen = (ScreenPtr) data;
-
- ephyrInternalDamageRedisplay (pScreen);
-}
-
-static void
-ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask)
-{
- /* FIXME: Not needed ? */
-}
-
-Bool
-ephyrSetInternalDamage (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- PixmapPtr pPixmap = NULL;
-
- scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
- (DamageDestroyFunc) 0,
- DamageReportNone,
- TRUE,
- pScreen,
- pScreen);
-
- if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
- ephyrInternalDamageWakeupHandler,
- (pointer) pScreen))
- return FALSE;
-
- pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
-
- DamageRegister (&pPixmap->drawable, scrpriv->pDamage);
-
- return TRUE;
-}
-
-void
-ephyrUnsetInternalDamage (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- PixmapPtr pPixmap = NULL;
-
- pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
- DamageUnregister (&pPixmap->drawable, scrpriv->pDamage);
- DamageDestroy (scrpriv->pDamage);
-
- RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
- ephyrInternalDamageWakeupHandler,
- (pointer) pScreen);
-}
-
-#ifdef RANDR
-Bool
-ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- RRScreenSizePtr pSize;
- Rotation randr;
- int n = 0;
-
- struct { int width, height; } sizes[] =
- {
- { 1600, 1200 },
- { 1400, 1050 },
- { 1280, 960 },
- { 1280, 1024 },
- { 1152, 864 },
- { 1024, 768 },
- { 832, 624 },
- { 800, 600 },
- { 720, 400 },
- { 480, 640 },
- { 640, 480 },
- { 640, 400 },
- { 320, 240 },
- { 240, 320 },
- { 160, 160 },
- { 0, 0 }
- };
-
- EPHYR_LOG("mark");
-
- *rotations = RR_Rotate_All|RR_Reflect_All;
-
- if (!hostx_want_preexisting_window (screen)
- && !hostx_want_fullscreen ()) /* only if no -parent switch */
- {
- while (sizes[n].width != 0 && sizes[n].height != 0)
- {
- RRRegisterSize (pScreen,
- sizes[n].width,
- sizes[n].height,
- (sizes[n].width * screen->width_mm)/screen->width,
- (sizes[n].height *screen->height_mm)/screen->height
- );
- n++;
- }
- }
-
- pSize = RRRegisterSize (pScreen,
- screen->width,
- screen->height,
- screen->width_mm,
- screen->height_mm);
-
- randr = KdSubRotation (scrpriv->randr, screen->randr);
-
- RRSetCurrentConfig (pScreen, randr, 0, pSize);
-
- return TRUE;
-}
-
-Bool
-ephyrRandRSetConfig (ScreenPtr pScreen,
- Rotation randr,
- int rate,
- RRScreenSizePtr pSize)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- Bool wasEnabled = pScreenPriv->enabled;
- EphyrScrPriv oldscr;
- int oldwidth, oldheight, oldmmwidth, oldmmheight;
- Bool oldshadow;
- int newwidth, newheight;
-
- if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
- {
- newwidth = pSize->width;
- newheight = pSize->height;
- }
- else
- {
- newwidth = pSize->height;
- newheight = pSize->width;
- }
-
- if (wasEnabled)
- KdDisableScreen (pScreen);
-
- oldscr = *scrpriv;
-
- oldwidth = screen->width;
- oldheight = screen->height;
- oldmmwidth = pScreen->mmWidth;
- oldmmheight = pScreen->mmHeight;
- oldshadow = scrpriv->shadow;
-
- /*
- * Set new configuration
- */
-
- scrpriv->randr = KdAddRotation (screen->randr, randr);
-
- ephyrUnmapFramebuffer (screen);
-
- screen->width = newwidth;
- screen->height = newheight;
-
- if (!ephyrMapFramebuffer (screen))
- goto bail4;
-
- /* FIXME below should go in own call */
-
- if (oldshadow)
- KdShadowUnset (screen->pScreen);
- else
- ephyrUnsetInternalDamage(screen->pScreen);
-
- if (scrpriv->shadow)
- {
- if (!KdShadowSet (screen->pScreen,
- scrpriv->randr,
- ephyrShadowUpdate,
- ephyrWindowLinear))
- goto bail4;
- }
- else
- {
- /* Without shadow fb ( non rotated ) we need
- * to use damage to efficiently update display
- * via signal regions what to copy from 'fb'.
- */
- if (!ephyrSetInternalDamage(screen->pScreen))
- goto bail4;
- }
-
- ephyrSetScreenSizes (screen->pScreen);
-
- /*
- * Set frame buffer mapping
- */
- (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
- pScreen->width,
- pScreen->height,
- screen->fb.depth,
- screen->fb.bitsPerPixel,
- screen->fb.byteStride,
- screen->fb.frameBuffer);
-
- /* set the subpixel order */
-
- KdSetSubpixelOrder (pScreen, scrpriv->randr);
-
- if (wasEnabled)
- KdEnableScreen (pScreen);
-
- return TRUE;
-
- bail4:
- EPHYR_LOG("bailed");
-
- ephyrUnmapFramebuffer (screen);
- *scrpriv = oldscr;
- (void) ephyrMapFramebuffer (screen);
-
- pScreen->width = oldwidth;
- pScreen->height = oldheight;
- pScreen->mmWidth = oldmmwidth;
- pScreen->mmHeight = oldmmheight;
-
- if (wasEnabled)
- KdEnableScreen (pScreen);
- return FALSE;
-}
-
-Bool
-ephyrRandRInit (ScreenPtr pScreen)
-{
- rrScrPrivPtr pScrPriv;
-
- if (!RRScreenInit (pScreen))
- return FALSE;
-
- pScrPriv = rrGetScrPriv(pScreen);
- pScrPriv->rrGetInfo = ephyrRandRGetInfo;
- pScrPriv->rrSetConfig = ephyrRandRSetConfig;
- return TRUE;
-}
-#endif
-
-Bool
-ephyrCreateColormap (ColormapPtr pmap)
-{
- return fbInitializeColormap (pmap);
-}
-
-Bool
-ephyrInitScreen (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
-
- EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
- hostx_set_screen_number (screen, pScreen->myNum);
- hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
- pScreen->CreateColormap = ephyrCreateColormap;
-
-#ifdef XV
- if (!ephyrNoXV) {
- if (!ephyrInitVideo (pScreen)) {
- EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
- } else {
- EPHYR_LOG ("initialized xvideo okay\n") ;
- }
- }
-#endif /*XV*/
-
-#ifdef XF86DRI
- if (!ephyrNoDRI && !hostx_has_dri ()) {
- EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ;
- ephyrNoDRI = TRUE ;
-#ifdef GLXEXT
- noGlxVisualInit = FALSE ;
-#endif
- }
- if (!ephyrNoDRI) {
- ephyrDRIExtensionInit (pScreen) ;
- ephyrHijackGLXExtension () ;
- }
-#endif
-
-#ifdef GLXEXT
- if (ephyrNoDRI) {
- noGlxVisualInit = FALSE ;
- }
-#endif
-
- return TRUE;
-}
-
-Bool
-ephyrFinishInitScreen (ScreenPtr pScreen)
-{
- /* FIXME: Calling this even if not using shadow.
- * Seems harmless enough. But may be safer elsewhere.
- */
- if (!shadowSetup (pScreen))
- return FALSE;
-
-#ifdef RANDR
- if (!ephyrRandRInit (pScreen))
- return FALSE;
-#endif
-
- return TRUE;
-}
-
-Bool
-ephyrCreateResources (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
-
- EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
- pScreen, pScreen->myNum, scrpriv->shadow);
-
- if (scrpriv->shadow)
- return KdShadowSet (pScreen,
- scrpriv->randr,
- ephyrShadowUpdate,
- ephyrWindowLinear);
- else
- return ephyrSetInternalDamage(pScreen);
-}
-
-void
-ephyrPreserve (KdCardInfo *card)
-{
-}
-
-Bool
-ephyrEnable (ScreenPtr pScreen)
-{
- return TRUE;
-}
-
-Bool
-ephyrDPMS (ScreenPtr pScreen, int mode)
-{
- return TRUE;
-}
-
-void
-ephyrDisable (ScreenPtr pScreen)
-{
-}
-
-void
-ephyrRestore (KdCardInfo *card)
-{
-}
-
-void
-ephyrScreenFini (KdScreenInfo *screen)
-{
- EphyrScrPriv *scrpriv = screen->driver;
- if (scrpriv->shadow) {
- KdShadowFbFree (screen);
- }
- xfree(screen->driver);
- screen->driver = NULL;
-}
-
-/*
- * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
- * See https://bugs.freedesktop.org/show_bug.cgi?id=3030
- */
-void
-ephyrUpdateModifierState(unsigned int state)
-{
-#if 0
- DeviceIntPtr pkeydev;
- KeyClassPtr keyc;
- int i;
- CARD8 mask;
-
- pkeydev = inputInfo.keyboard;
-
- if (!pkeydev)
- return;
-
-/* This is pretty broken.
- *
- * What should happen is that focus out should do as a VT switch does in
- * traditional servers: fake releases for all keys (and buttons too, come
- * to think of it) currently down. Then, on focus in, get the state from
- * the host, and fake keypresses for everything currently down.
- *
- * So I'm leaving this broken for a little while. Sorry, folks.
- *
- * -daniels
- */
-
- keyc = pkeydev->key;
-
- state = state & 0xff;
-
- if (keyc->state == state)
- return;
-
- for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
- {
- int key;
-
- /* Modifier is down, but shouldn't be */
- if ((keyc->state & mask) && !(state & mask))
- {
- int count = keyc->modifierKeyCount[i];
-
- for (key = 0; key < MAP_LENGTH; key++)
- if (keyc->xkbInfo->desc->map->modmap[key] & mask)
- {
- int bit;
- BYTE *kptr;
-
- kptr = &keyc->down[key >> 3];
- bit = 1 << (key & 7);
-
- if (*kptr & bit && ephyrKbd &&
- ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
- KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
-
- if (--count == 0)
- break;
- }
- }
-
- /* Modifier shoud be down, but isn't */
- if (!(keyc->state & mask) && (state & mask))
- for (key = 0; key < MAP_LENGTH; key++)
- if (keyc->xkbInfo->desc->map->modmap[key] & mask)
- {
- if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
- ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
- KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
- break;
- }
- }
-#endif
-}
-
-static void
-ephyrBlockSigio (void)
-{
- sigset_t set;
-
- sigemptyset (&set);
- sigaddset (&set, SIGIO);
- sigprocmask (SIG_BLOCK, &set, 0);
-}
-
-static void
-ephyrUnblockSigio (void)
-{
- sigset_t set;
-
- sigemptyset (&set);
- sigaddset (&set, SIGIO);
- sigprocmask (SIG_UNBLOCK, &set, 0);
-}
-
-static Bool
-ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
-{
- return FALSE;
-}
-
-static void
-ephyrCrossScreen (ScreenPtr pScreen, Bool entering)
-{
-}
-
-int ephyrCurScreen; /*current event screen*/
-
-static void
-ephyrWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- ephyrBlockSigio ();
- ephyrCurScreen = pScreen->myNum;
- miPointerWarpCursor (inputInfo.pointer, pScreen, x, y);
- ephyrUnblockSigio ();
-}
-
-miPointerScreenFuncRec ephyrPointerScreenFuncs =
-{
- ephyrCursorOffScreen,
- ephyrCrossScreen,
- ephyrWarpCursor,
- NULL,
- NULL
-};
-
-#ifdef XF86DRI
-/**
- * find if the remote window denoted by a_remote
- * is paired with an internal Window within the Xephyr server.
- * If the remove window is paired with an internal window, send an
- * expose event to the client insterested in the internal window expose event.
- *
- * Pairing happens when a drawable inside Xephyr is associated with
- * a GL surface in a DRI environment.
- * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to
- * know a paired window is created.
- *
- * This is useful to make GL drawables (only windows for now) handle
- * expose events and send those events to clients.
- */
-static void
-ephyrExposePairedWindow (int a_remote)
-{
- EphyrWindowPair *pair = NULL;
- RegionRec reg;
- ScreenPtr screen;
-
- if (!findWindowPairFromRemote (a_remote, &pair)) {
- EPHYR_LOG ("did not find a pair for this window\n");
- return;
- }
- screen = pair->local->drawable.pScreen;
- REGION_NULL (screen, &reg);
- REGION_COPY (screen, &reg, &pair->local->clipList);
- screen->WindowExposures (pair->local, &reg, NullRegion);
- REGION_UNINIT (screen, &reg);
-}
-#endif /* XF86DRI */
-
-void
-ephyrPoll(void)
-{
- EphyrHostXEvent ev;
-
- while (hostx_get_event(&ev))
- {
- switch (ev.type)
- {
- case EPHYR_EV_MOUSE_MOTION:
- if (!ephyrMouse ||
- !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
- EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
- continue;
- }
- {
- if (ev.data.mouse_motion.screen >=0
- && (ephyrCurScreen != ev.data.mouse_motion.screen))
- {
- EPHYR_LOG ("warping mouse cursor. "
- "cur_screen%d, motion_screen:%d\n",
- ephyrCurScreen, ev.data.mouse_motion.screen) ;
- if (ev.data.mouse_motion.screen >= 0)
- {
- ephyrWarpCursor
- (inputInfo.pointer, screenInfo.screens[ev.data.mouse_motion.screen],
- ev.data.mouse_motion.x,
- ev.data.mouse_motion.y );
- }
- }
- else
- {
- int x=0, y=0;
-#ifdef XF86DRI
- EphyrWindowPair *pair = NULL;
-#endif
- EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
- x = ev.data.mouse_motion.x;
- y = ev.data.mouse_motion.y;
- EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ;
-#ifdef XF86DRI
- EPHYR_LOG ("is this window peered by a gl drawable ?\n") ;
- if (findWindowPairFromRemote (ev.data.mouse_motion.window,
- &pair))
- {
- EPHYR_LOG ("yes, it is peered\n") ;
- x += pair->local->drawable.x;
- y += pair->local->drawable.y;
- }
- else
- {
- EPHYR_LOG ("no, it is not peered\n") ;
- }
- EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ;
-#endif
- KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
- }
- }
- break;
-
- case EPHYR_EV_MOUSE_PRESS:
- if (!ephyrMouse ||
- !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
- EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
- continue;
- }
- EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
- ephyrUpdateModifierState(ev.key_state);
- mouseState |= ev.data.mouse_down.button_num;
- KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
- break;
-
- case EPHYR_EV_MOUSE_RELEASE:
- if (!ephyrMouse ||
- !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
- continue;
- ephyrUpdateModifierState(ev.key_state);
- mouseState &= ~ev.data.mouse_up.button_num;
- EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
- KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
- break;
-
- case EPHYR_EV_KEY_PRESS:
- if (!ephyrKbd ||
- !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
- continue;
- ephyrUpdateModifierState(ev.key_state);
- KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE);
- break;
-
- case EPHYR_EV_KEY_RELEASE:
- if (!ephyrKbd ||
- !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
- continue;
- KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
- break;
-
-#ifdef XF86DRI
- case EPHYR_EV_EXPOSE:
- /*
- * We only receive expose events when the expose event have
- * be generated for a drawable that is a host X window managed
- * by Xephyr. Host X windows managed by Xephyr exists for instance
- * when Xephyr is asked to create a GL drawable in a DRI environment.
- */
- ephyrExposePairedWindow (ev.data.expose.window);
- break;
-#endif /* XF86DRI */
-
- default:
- break;
- }
- }
-}
-
-void
-ephyrCardFini (KdCardInfo *card)
-{
- EphyrPriv *priv = card->driver;
- xfree (priv);
-}
-
-void
-ephyrGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
-{
- /* XXX Not sure if this is right */
-
- EPHYR_LOG("mark");
-
- while (n--)
- {
- pdefs->red = 0;
- pdefs->green = 0;
- pdefs->blue = 0;
- pdefs++;
- }
-
-}
-
-void
-ephyrPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
-{
- int min, max, p;
-
- /* XXX Not sure if this is right */
-
- min = 256;
- max = 0;
-
- while (n--)
- {
- p = pdefs->pixel;
- if (p < min)
- min = p;
- if (p > max)
- max = p;
-
- hostx_set_cmap_entry(p,
- pdefs->red >> 8,
- pdefs->green >> 8,
- pdefs->blue >> 8);
- pdefs++;
- }
-}
-
-/* Mouse calls */
-
-static Status
-MouseInit (KdPointerInfo *pi)
-{
- pi->driverPrivate = (EphyrPointerPrivate *)
- xcalloc(sizeof(EphyrPointerPrivate), 1);
- ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
- pi->nAxes = 3;
- pi->nButtons = 32;
- xfree(pi->name);
- pi->name = strdup("Xephyr virtual mouse");
- ephyrMouse = pi;
- return Success;
-}
-
-static Status
-MouseEnable (KdPointerInfo *pi)
-{
- ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE;
- return Success;
-}
-
-static void
-MouseDisable (KdPointerInfo *pi)
-{
- ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
- return;
-}
-
-static void
-MouseFini (KdPointerInfo *pi)
-{
- ephyrMouse = NULL;
- return;
-}
-
-KdPointerDriver EphyrMouseDriver = {
- "ephyr",
- MouseInit,
- MouseEnable,
- MouseDisable,
- MouseFini,
- NULL,
-};
-
-/* Keyboard */
-
-static Status
-EphyrKeyboardInit (KdKeyboardInfo *ki)
-{
- ki->driverPrivate = (EphyrKbdPrivate *)
- xcalloc(sizeof(EphyrKbdPrivate), 1);
- hostx_load_keymap();
- if (!ephyrKeySyms.map) {
- ErrorF("Couldn't load keymap from host\n");
- return BadAlloc;
- }
- ki->minScanCode = ephyrKeySyms.minKeyCode;
- ki->maxScanCode = ephyrKeySyms.maxKeyCode;
- xfree(ki->name);
- ki->name = strdup("Xephyr virtual keyboard");
- ephyrKbd = ki;
- return Success;
-}
-
-static Status
-EphyrKeyboardEnable (KdKeyboardInfo *ki)
-{
- ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE;
-
- return Success;
-}
-
-static void
-EphyrKeyboardDisable (KdKeyboardInfo *ki)
-{
- ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE;
-}
-
-static void
-EphyrKeyboardFini (KdKeyboardInfo *ki)
-{
- ephyrKbd = NULL;
- return;
-}
-
-static void
-EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds)
-{
-}
-
-static void
-EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
-{
-}
-
-
-KdKeyboardDriver EphyrKeyboardDriver = {
- "ephyr",
- EphyrKeyboardInit,
- EphyrKeyboardEnable,
- EphyrKeyboardLeds,
- EphyrKeyboardBell,
- EphyrKeyboardDisable,
- EphyrKeyboardFini,
- NULL,
-};
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "ephyrlog.h"
+
+#ifdef XF86DRI
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "ephyrglxext.h"
+#endif /* XF86DRI */
+
+extern int KdTsPhyScreen;
+#ifdef GLXEXT
+extern Bool noGlxVisualInit;
+#endif
+
+KdKeyboardInfo *ephyrKbd;
+KdPointerInfo *ephyrMouse;
+EphyrKeySyms ephyrKeySyms;
+Bool ephyrNoDRI=FALSE ;
+Bool ephyrNoXV=FALSE ;
+
+static int mouseState = 0;
+
+typedef struct _EphyrInputPrivate {
+ Bool enabled;
+} EphyrKbdPrivate, EphyrPointerPrivate;
+
+Bool EphyrWantGrayScale = 0;
+
+
+Bool
+ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
+{
+ OsSignal(SIGUSR1, hostx_handle_signal);
+
+ priv->base = 0;
+ priv->bytes_per_line = 0;
+ return TRUE;
+}
+
+Bool
+ephyrCardInit (KdCardInfo *card)
+{
+ EphyrPriv *priv;
+
+ priv = (EphyrPriv *) malloc(sizeof (EphyrPriv));
+ if (!priv)
+ return FALSE;
+
+ if (!ephyrInitialize (card, priv))
+ {
+ free(priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+Bool
+ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
+{
+ int width = 640, height = 480;
+ CARD32 redMask, greenMask, blueMask;
+
+ if (hostx_want_screen_size(screen, &width, &height)
+ || !screen->width || !screen->height)
+ {
+ screen->width = width;
+ screen->height = height;
+ }
+
+ if (EphyrWantGrayScale)
+ screen->fb.depth = 8;
+
+ if (screen->fb.depth && screen->fb.depth != hostx_get_depth())
+ {
+ if (screen->fb.depth < hostx_get_depth()
+ && (screen->fb.depth == 24 || screen->fb.depth == 16
+ || screen->fb.depth == 8))
+ {
+ hostx_set_server_depth(screen, screen->fb.depth);
+ }
+ else
+ ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
+ }
+
+ screen->fb.depth = hostx_get_server_depth(screen);
+ screen->rate = 72;
+
+ if (screen->fb.depth <= 8)
+ {
+ if (EphyrWantGrayScale)
+ screen->fb.visuals = ((1 << StaticGray) | (1 << GrayScale));
+ else
+ screen->fb.visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+
+ screen->fb.redMask = 0x00;
+ screen->fb.greenMask = 0x00;
+ screen->fb.blueMask = 0x00;
+ screen->fb.depth = 8;
+ screen->fb.bitsPerPixel = 8;
+ }
+ else
+ {
+ screen->fb.visuals = (1 << TrueColor);
+
+ if (screen->fb.depth <= 15)
+ {
+ screen->fb.depth = 15;
+ screen->fb.bitsPerPixel = 16;
+ }
+ else if (screen->fb.depth <= 16)
+ {
+ screen->fb.depth = 16;
+ screen->fb.bitsPerPixel = 16;
+ }
+ else if (screen->fb.depth <= 24)
+ {
+ screen->fb.depth = 24;
+ screen->fb.bitsPerPixel = 32;
+ }
+ else if (screen->fb.depth <= 30)
+ {
+ screen->fb.depth = 30;
+ screen->fb.bitsPerPixel = 32;
+ }
+ else
+ {
+ ErrorF("\nXephyr: Unsupported screen depth %d\n",
+ screen->fb.depth);
+ return FALSE;
+ }
+
+ hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
+
+ screen->fb.redMask = (Pixel) redMask;
+ screen->fb.greenMask = (Pixel) greenMask;
+ screen->fb.blueMask = (Pixel) blueMask;
+
+ }
+
+ scrpriv->randr = screen->randr;
+
+ return ephyrMapFramebuffer (screen);
+}
+
+Bool
+ephyrScreenInit (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv;
+
+ scrpriv = calloc(1, sizeof (EphyrScrPriv));
+
+ if (!scrpriv)
+ return FALSE;
+
+ screen->driver = scrpriv;
+
+ if (!ephyrScreenInitialize (screen, scrpriv))
+ {
+ screen->driver = 0;
+ free(scrpriv);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void*
+ephyrWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ EphyrPriv *priv = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ *size = priv->bytes_per_line;
+ return priv->base + row * priv->bytes_per_line + offset;
+}
+
+/**
+ * Figure out display buffer size. If fakexa is enabled, allocate a larger
+ * buffer so that fakexa has space to put offscreen pixmaps.
+ */
+int
+ephyrBufferHeight(KdScreenInfo *screen)
+{
+ int buffer_height;
+ if (ephyrFuncs.initAccel == NULL)
+ buffer_height = screen->height;
+ else
+ buffer_height = 3 * screen->height;
+ return buffer_height;
+}
+
+
+Bool
+ephyrMapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrPriv *priv = screen->card->driver;
+ KdPointerMatrix m;
+ int buffer_height;
+
+ EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
+ screen->width, screen->height, screen->mynum);
+
+ KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
+ KdSetPointerMatrix (&m);
+
+ priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
+
+ buffer_height = ephyrBufferHeight(screen);
+
+ priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
+
+ if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All))
+ {
+ scrpriv->shadow = FALSE;
+
+ screen->fb.byteStride = priv->bytes_per_line;
+ screen->fb.pixelStride = screen->width;
+ screen->fb.frameBuffer = (CARD8 *) (priv->base);
+ }
+ else
+ {
+ /* Rotated/Reflected so we need to use shadow fb */
+ scrpriv->shadow = TRUE;
+
+ EPHYR_LOG("allocing shadow");
+
+ KdShadowFbAlloc (screen,
+ scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
+ }
+
+ return TRUE;
+}
+
+void
+ephyrSetScreenSizes (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ }
+ else
+ {
+ pScreen->width = screen->height;
+ pScreen->height = screen->width;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ }
+}
+
+Bool
+ephyrUnmapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->shadow)
+ KdShadowFbFree (screen);
+
+ /* Note, priv->base will get freed when XImage recreated */
+
+ return TRUE;
+}
+
+void
+ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG("slow paint");
+
+ /* FIXME: Slow Rotated/Reflected updates could be much
+ * much faster efficiently updating via tranforming
+ * pBuf->pDamage regions
+ */
+ shadowUpdateRotatePacked(pScreen, pBuf);
+ hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
+}
+
+static void
+ephyrInternalDamageRedisplay (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RegionPtr pRegion;
+
+ if (!scrpriv || !scrpriv->pDamage)
+ return;
+
+ pRegion = DamageRegion (scrpriv->pDamage);
+
+ if (REGION_NOTEMPTY (pScreen, pRegion))
+ {
+ int nbox;
+ BoxPtr pbox;
+
+ nbox = REGION_NUM_RECTS (pRegion);
+ pbox = REGION_RECTS (pRegion);
+
+ while (nbox--)
+ {
+ hostx_paint_rect(screen,
+ pbox->x1, pbox->y1,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ DamageEmpty (scrpriv->pDamage);
+ }
+}
+
+static void
+ephyrInternalDamageBlockHandler (pointer data,
+ OSTimePtr pTimeout,
+ pointer pRead)
+{
+ ScreenPtr pScreen = (ScreenPtr) data;
+
+ ephyrInternalDamageRedisplay (pScreen);
+}
+
+static void
+ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask)
+{
+ /* FIXME: Not needed ? */
+}
+
+Bool
+ephyrSetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
+ (DamageDestroyFunc) 0,
+ DamageReportNone,
+ TRUE,
+ pScreen,
+ pScreen);
+
+ if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen))
+ return FALSE;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+
+ DamageRegister (&pPixmap->drawable, scrpriv->pDamage);
+
+ return TRUE;
+}
+
+void
+ephyrUnsetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ DamageUnregister (&pPixmap->drawable, scrpriv->pDamage);
+ DamageDestroy (scrpriv->pDamage);
+
+ RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen);
+}
+
+#ifdef RANDR
+Bool
+ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RRScreenSizePtr pSize;
+ Rotation randr;
+ int n = 0;
+
+ struct { int width, height; } sizes[] =
+ {
+ { 1600, 1200 },
+ { 1400, 1050 },
+ { 1280, 960 },
+ { 1280, 1024 },
+ { 1152, 864 },
+ { 1024, 768 },
+ { 832, 624 },
+ { 800, 600 },
+ { 720, 400 },
+ { 480, 640 },
+ { 640, 480 },
+ { 640, 400 },
+ { 320, 240 },
+ { 240, 320 },
+ { 160, 160 },
+ { 0, 0 }
+ };
+
+ EPHYR_LOG("mark");
+
+ *rotations = RR_Rotate_All|RR_Reflect_All;
+
+ if (!hostx_want_preexisting_window (screen)
+ && !hostx_want_fullscreen ()) /* only if no -parent switch */
+ {
+ while (sizes[n].width != 0 && sizes[n].height != 0)
+ {
+ RRRegisterSize (pScreen,
+ sizes[n].width,
+ sizes[n].height,
+ (sizes[n].width * screen->width_mm)/screen->width,
+ (sizes[n].height *screen->height_mm)/screen->height
+ );
+ n++;
+ }
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm);
+
+ randr = KdSubRotation (scrpriv->randr, screen->randr);
+
+ RRSetCurrentConfig (pScreen, randr, 0, pSize);
+
+ return TRUE;
+}
+
+Bool
+ephyrRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ Bool wasEnabled = pScreenPriv->enabled;
+ EphyrScrPriv oldscr;
+ int oldwidth, oldheight, oldmmwidth, oldmmheight;
+ Bool oldshadow;
+ int newwidth, newheight;
+
+ if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ newwidth = pSize->width;
+ newheight = pSize->height;
+ }
+ else
+ {
+ newwidth = pSize->height;
+ newheight = pSize->width;
+ }
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ oldscr = *scrpriv;
+
+ oldwidth = screen->width;
+ oldheight = screen->height;
+ oldmmwidth = pScreen->mmWidth;
+ oldmmheight = pScreen->mmHeight;
+ oldshadow = scrpriv->shadow;
+
+ /*
+ * Set new configuration
+ */
+
+ scrpriv->randr = KdAddRotation (screen->randr, randr);
+
+ ephyrUnmapFramebuffer (screen);
+
+ screen->width = newwidth;
+ screen->height = newheight;
+
+ if (!ephyrMapFramebuffer (screen))
+ goto bail4;
+
+ /* FIXME below should go in own call */
+
+ if (oldshadow)
+ KdShadowUnset (screen->pScreen);
+ else
+ ephyrUnsetInternalDamage(screen->pScreen);
+
+ if (scrpriv->shadow)
+ {
+ if (!KdShadowSet (screen->pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear))
+ goto bail4;
+ }
+ else
+ {
+ /* Without shadow fb ( non rotated ) we need
+ * to use damage to efficiently update display
+ * via signal regions what to copy from 'fb'.
+ */
+ if (!ephyrSetInternalDamage(screen->pScreen))
+ goto bail4;
+ }
+
+ ephyrSetScreenSizes (screen->pScreen);
+
+ /*
+ * Set frame buffer mapping
+ */
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb.depth,
+ screen->fb.bitsPerPixel,
+ screen->fb.byteStride,
+ screen->fb.frameBuffer);
+
+ /* set the subpixel order */
+
+ KdSetSubpixelOrder (pScreen, scrpriv->randr);
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+
+ return TRUE;
+
+ bail4:
+ EPHYR_LOG("bailed");
+
+ ephyrUnmapFramebuffer (screen);
+ *scrpriv = oldscr;
+ (void) ephyrMapFramebuffer (screen);
+
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmwidth;
+ pScreen->mmHeight = oldmmheight;
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+}
+
+Bool
+ephyrRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = ephyrRandRGetInfo;
+ pScrPriv->rrSetConfig = ephyrRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+Bool
+ephyrCreateColormap (ColormapPtr pmap)
+{
+ return fbInitializeColormap (pmap);
+}
+
+Bool
+ephyrInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
+ hostx_set_screen_number (screen, pScreen->myNum);
+ hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
+ pScreen->CreateColormap = ephyrCreateColormap;
+
+#ifdef XV
+ if (!ephyrNoXV) {
+ if (!ephyrInitVideo (pScreen)) {
+ EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
+ } else {
+ EPHYR_LOG ("initialized xvideo okay\n") ;
+ }
+ }
+#endif /*XV*/
+
+#ifdef XF86DRI
+ if (!ephyrNoDRI && !hostx_has_dri ()) {
+ EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ;
+ ephyrNoDRI = TRUE ;
+#ifdef GLXEXT
+ noGlxVisualInit = FALSE ;
+#endif
+ }
+ if (!ephyrNoDRI) {
+ ephyrDRIExtensionInit (pScreen) ;
+ ephyrHijackGLXExtension () ;
+ }
+#endif
+
+#ifdef GLXEXT
+ if (ephyrNoDRI) {
+ noGlxVisualInit = FALSE ;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrFinishInitScreen (ScreenPtr pScreen)
+{
+ /* FIXME: Calling this even if not using shadow.
+ * Seems harmless enough. But may be safer elsewhere.
+ */
+ if (!shadowSetup (pScreen))
+ return FALSE;
+
+#ifdef RANDR
+ if (!ephyrRandRInit (pScreen))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrCreateResources (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
+ pScreen, pScreen->myNum, scrpriv->shadow);
+
+ if (scrpriv->shadow)
+ return KdShadowSet (pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear);
+ else
+ return ephyrSetInternalDamage(pScreen);
+}
+
+void
+ephyrPreserve (KdCardInfo *card)
+{
+}
+
+Bool
+ephyrEnable (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+ephyrDPMS (ScreenPtr pScreen, int mode)
+{
+ return TRUE;
+}
+
+void
+ephyrDisable (ScreenPtr pScreen)
+{
+}
+
+void
+ephyrRestore (KdCardInfo *card)
+{
+}
+
+void
+ephyrScreenFini (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ if (scrpriv->shadow) {
+ KdShadowFbFree (screen);
+ }
+ free(screen->driver);
+ screen->driver = NULL;
+}
+
+/*
+ * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=3030
+ */
+void
+ephyrUpdateModifierState(unsigned int state)
+{
+#if 0
+ DeviceIntPtr pkeydev;
+ KeyClassPtr keyc;
+ int i;
+ CARD8 mask;
+
+ pkeydev = inputInfo.keyboard;
+
+ if (!pkeydev)
+ return;
+
+/* This is pretty broken.
+ *
+ * What should happen is that focus out should do as a VT switch does in
+ * traditional servers: fake releases for all keys (and buttons too, come
+ * to think of it) currently down. Then, on focus in, get the state from
+ * the host, and fake keypresses for everything currently down.
+ *
+ * So I'm leaving this broken for a little while. Sorry, folks.
+ *
+ * -daniels
+ */
+
+ keyc = pkeydev->key;
+
+ state = state & 0xff;
+
+ if (keyc->state == state)
+ return;
+
+ for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
+ {
+ int key;
+
+ /* Modifier is down, but shouldn't be */
+ if ((keyc->state & mask) && !(state & mask))
+ {
+ int count = keyc->modifierKeyCount[i];
+
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask)
+ {
+ int bit;
+ BYTE *kptr;
+
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+
+ if (*kptr & bit && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
+
+ if (--count == 0)
+ break;
+ }
+ }
+
+ /* Modifier shoud be down, but isn't */
+ if (!(keyc->state & mask) && (state & mask))
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask)
+ {
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
+ break;
+ }
+ }
+#endif
+}
+
+static void
+ephyrBlockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+}
+
+static void
+ephyrUnblockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+}
+
+static Bool
+ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+static void
+ephyrCrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+int ephyrCurScreen; /*current event screen*/
+
+static void
+ephyrWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ ephyrBlockSigio ();
+ ephyrCurScreen = pScreen->myNum;
+ miPointerWarpCursor (inputInfo.pointer, pScreen, x, y);
+ ephyrUnblockSigio ();
+}
+
+miPointerScreenFuncRec ephyrPointerScreenFuncs =
+{
+ ephyrCursorOffScreen,
+ ephyrCrossScreen,
+ ephyrWarpCursor,
+ NULL,
+ NULL
+};
+
+#ifdef XF86DRI
+/**
+ * find if the remote window denoted by a_remote
+ * is paired with an internal Window within the Xephyr server.
+ * If the remove window is paired with an internal window, send an
+ * expose event to the client insterested in the internal window expose event.
+ *
+ * Pairing happens when a drawable inside Xephyr is associated with
+ * a GL surface in a DRI environment.
+ * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to
+ * know a paired window is created.
+ *
+ * This is useful to make GL drawables (only windows for now) handle
+ * expose events and send those events to clients.
+ */
+static void
+ephyrExposePairedWindow (int a_remote)
+{
+ EphyrWindowPair *pair = NULL;
+ RegionRec reg;
+ ScreenPtr screen;
+
+ if (!findWindowPairFromRemote (a_remote, &pair)) {
+ EPHYR_LOG ("did not find a pair for this window\n");
+ return;
+ }
+ screen = pair->local->drawable.pScreen;
+ REGION_NULL (screen, &reg);
+ REGION_COPY (screen, &reg, &pair->local->clipList);
+ screen->WindowExposures (pair->local, &reg, NullRegion);
+ REGION_UNINIT (screen, &reg);
+}
+#endif /* XF86DRI */
+
+void
+ephyrPoll(void)
+{
+ EphyrHostXEvent ev;
+
+ while (hostx_get_event(&ev))
+ {
+ switch (ev.type)
+ {
+ case EPHYR_EV_MOUSE_MOTION:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ {
+ if (ev.data.mouse_motion.screen >=0
+ && (ephyrCurScreen != ev.data.mouse_motion.screen))
+ {
+ EPHYR_LOG ("warping mouse cursor. "
+ "cur_screen%d, motion_screen:%d\n",
+ ephyrCurScreen, ev.data.mouse_motion.screen) ;
+ if (ev.data.mouse_motion.screen >= 0)
+ {
+ ephyrWarpCursor
+ (inputInfo.pointer, screenInfo.screens[ev.data.mouse_motion.screen],
+ ev.data.mouse_motion.x,
+ ev.data.mouse_motion.y );
+ }
+ }
+ else
+ {
+ int x=0, y=0;
+#ifdef XF86DRI
+ EphyrWindowPair *pair = NULL;
+#endif
+ EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
+ x = ev.data.mouse_motion.x;
+ y = ev.data.mouse_motion.y;
+ EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ;
+#ifdef XF86DRI
+ EPHYR_LOG ("is this window peered by a gl drawable ?\n") ;
+ if (findWindowPairFromRemote (ev.data.mouse_motion.window,
+ &pair))
+ {
+ EPHYR_LOG ("yes, it is peered\n") ;
+ x += pair->local->drawable.x;
+ y += pair->local->drawable.y;
+ }
+ else
+ {
+ EPHYR_LOG ("no, it is not peered\n") ;
+ }
+ EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ;
+#endif
+ KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
+ }
+ }
+ break;
+
+ case EPHYR_EV_MOUSE_PRESS:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState |= ev.data.mouse_down.button_num;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_MOUSE_RELEASE:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState &= ~ev.data.mouse_up.button_num;
+ EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_KEY_PRESS:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE);
+ break;
+
+ case EPHYR_EV_KEY_RELEASE:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
+ break;
+
+#ifdef XF86DRI
+ case EPHYR_EV_EXPOSE:
+ /*
+ * We only receive expose events when the expose event have
+ * be generated for a drawable that is a host X window managed
+ * by Xephyr. Host X windows managed by Xephyr exists for instance
+ * when Xephyr is asked to create a GL drawable in a DRI environment.
+ */
+ ephyrExposePairedWindow (ev.data.expose.window);
+ break;
+#endif /* XF86DRI */
+
+ default:
+ break;
+ }
+ }
+}
+
+void
+ephyrCardFini (KdCardInfo *card)
+{
+ EphyrPriv *priv = card->driver;
+ free(priv);
+}
+
+void
+ephyrGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ /* XXX Not sure if this is right */
+
+ EPHYR_LOG("mark");
+
+ while (n--)
+ {
+ pdefs->red = 0;
+ pdefs->green = 0;
+ pdefs->blue = 0;
+ pdefs++;
+ }
+
+}
+
+void
+ephyrPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ int min, max, p;
+
+ /* XXX Not sure if this is right */
+
+ min = 256;
+ max = 0;
+
+ while (n--)
+ {
+ p = pdefs->pixel;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+
+ hostx_set_cmap_entry(p,
+ pdefs->red >> 8,
+ pdefs->green >> 8,
+ pdefs->blue >> 8);
+ pdefs++;
+ }
+}
+
+/* Mouse calls */
+
+static Status
+MouseInit (KdPointerInfo *pi)
+{
+ pi->driverPrivate = (EphyrPointerPrivate *)
+ calloc(sizeof(EphyrPointerPrivate), 1);
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ pi->nAxes = 3;
+ pi->nButtons = 32;
+ free(pi->name);
+ pi->name = strdup("Xephyr virtual mouse");
+ ephyrMouse = pi;
+ return Success;
+}
+
+static Status
+MouseEnable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE;
+ return Success;
+}
+
+static void
+MouseDisable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ return;
+}
+
+static void
+MouseFini (KdPointerInfo *pi)
+{
+ ephyrMouse = NULL;
+ return;
+}
+
+KdPointerDriver EphyrMouseDriver = {
+ "ephyr",
+ MouseInit,
+ MouseEnable,
+ MouseDisable,
+ MouseFini,
+ NULL,
+};
+
+/* Keyboard */
+
+static Status
+EphyrKeyboardInit (KdKeyboardInfo *ki)
+{
+ ki->driverPrivate = (EphyrKbdPrivate *)
+ calloc(sizeof(EphyrKbdPrivate), 1);
+ hostx_load_keymap();
+ if (!ephyrKeySyms.map) {
+ ErrorF("Couldn't load keymap from host\n");
+ return BadAlloc;
+ }
+ ki->minScanCode = ephyrKeySyms.minKeyCode;
+ ki->maxScanCode = ephyrKeySyms.maxKeyCode;
+ free(ki->name);
+ ki->name = strdup("Xephyr virtual keyboard");
+ ephyrKbd = ki;
+ return Success;
+}
+
+static Status
+EphyrKeyboardEnable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE;
+
+ return Success;
+}
+
+static void
+EphyrKeyboardDisable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE;
+}
+
+static void
+EphyrKeyboardFini (KdKeyboardInfo *ki)
+{
+ ephyrKbd = NULL;
+ return;
+}
+
+static void
+EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds)
+{
+}
+
+static void
+EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
+{
+}
+
+
+KdKeyboardDriver EphyrKeyboardDriver = {
+ "ephyr",
+ EphyrKeyboardInit,
+ EphyrKeyboardEnable,
+ EphyrKeyboardLeds,
+ EphyrKeyboardBell,
+ EphyrKeyboardDisable,
+ EphyrKeyboardFini,
+ NULL,
+};
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],
- &REGION_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],
+ &REGION_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, &registered_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, &registered_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 ;
+}