summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GL/glx/g_disptab.h2
-rw-r--r--GL/glx/glxcmds.c751
-rw-r--r--GL/glx/glxcmdsswap.c134
-rw-r--r--GL/glx/glxcontext.h18
-rw-r--r--GL/glx/glxdrawable.h35
-rw-r--r--GL/glx/glxdri.c542
-rw-r--r--GL/glx/glxext.c254
-rw-r--r--GL/glx/glxext.h38
-rw-r--r--GL/glx/glxglcore.c5
-rw-r--r--GL/glx/glxscreens.c148
-rw-r--r--GL/glx/glxscreens.h29
-rw-r--r--GL/glx/glxserver.h5
-rw-r--r--GL/glx/glxutil.c11
-rw-r--r--GL/glx/glxutil.h2
-rw-r--r--GL/glx/glxvisuals.c8
-rw-r--r--GL/glx/indirect_dispatch.h22
-rw-r--r--GL/glx/indirect_size_get.c4
-rw-r--r--GL/glx/indirect_table.c6
-rw-r--r--Xext/shm.c98
-rw-r--r--configure.ac22
-rw-r--r--dix/events.c55
-rw-r--r--dix/extension.c2
-rw-r--r--exa/exa.c218
-rw-r--r--exa/exa.h19
-rw-r--r--exa/exa_accel.c81
-rw-r--r--exa/exa_migration.c3
-rw-r--r--exa/exa_priv.h4
-rw-r--r--fb/fbarc.c37
-rw-r--r--fb/fbcmap_mi.c8
-rw-r--r--hw/kdrive/ephyr/GL/internal/dri_interface.h517
-rw-r--r--hw/kdrive/ephyr/Makefile.am47
-rw-r--r--hw/kdrive/ephyr/XF86dri.c622
-rw-r--r--hw/kdrive/ephyr/ephyr.c229
-rw-r--r--hw/kdrive/ephyr/ephyr.h6
-rw-r--r--hw/kdrive/ephyr/ephyrdri.c291
-rw-r--r--hw/kdrive/ephyr/ephyrdri.h75
-rw-r--r--hw/kdrive/ephyr/ephyrdriext.c1448
-rw-r--r--hw/kdrive/ephyr/ephyrdriext.h32
-rw-r--r--hw/kdrive/ephyr/ephyrglxext.c722
-rw-r--r--hw/kdrive/ephyr/ephyrglxext.h35
-rw-r--r--hw/kdrive/ephyr/ephyrhostglx.c687
-rw-r--r--hw/kdrive/ephyr/ephyrhostglx.h76
-rw-r--r--hw/kdrive/ephyr/ephyrhostproxy.c94
-rw-r--r--hw/kdrive/ephyr/ephyrhostproxy.h51
-rw-r--r--hw/kdrive/ephyr/ephyrhostvideo.c1004
-rw-r--r--hw/kdrive/ephyr/ephyrhostvideo.h238
-rw-r--r--hw/kdrive/ephyr/ephyrinit.c110
-rw-r--r--hw/kdrive/ephyr/ephyrlog.h67
-rw-r--r--hw/kdrive/ephyr/ephyrproxyext.c119
-rw-r--r--hw/kdrive/ephyr/ephyrproxyext.h34
-rw-r--r--hw/kdrive/ephyr/ephyrvideo.c1278
-rw-r--r--hw/kdrive/ephyr/hostx.c1055
-rw-r--r--hw/kdrive/ephyr/hostx.h122
-rw-r--r--hw/kdrive/ephyr/os.c10
-rw-r--r--hw/kdrive/fbdev/Makefile.am2
-rw-r--r--hw/kdrive/src/Makefile.am2
-rw-r--r--hw/xfree86/common/xf86AutoConfig.c231
-rw-r--r--hw/xfree86/common/xf86Config.c38
-rw-r--r--hw/xfree86/common/xf86Config.h5
-rw-r--r--hw/xfree86/common/xf86Events.c4
-rw-r--r--hw/xfree86/common/xf86Globals.c2
-rw-r--r--hw/xfree86/common/xf86Helper.c2
-rw-r--r--hw/xfree86/common/xf86Init.c10
-rw-r--r--hw/xfree86/common/xf86Privstr.h2
-rw-r--r--hw/xfree86/common/xf86str.h1
-rw-r--r--hw/xfree86/dri/dri.c4
-rw-r--r--hw/xfree86/modes/xf86Crtc.c61
-rw-r--r--hw/xfree86/modes/xf86Crtc.h3
-rw-r--r--hw/xfree86/modes/xf86EdidModes.c207
-rw-r--r--hw/xfree86/modes/xf86Modes.c11
-rw-r--r--hw/xfree86/modes/xf86Modes.h3
-rw-r--r--hw/xfree86/os-support/assyntax.h2
-rw-r--r--hw/xfree86/os-support/bus/Pci.h2
-rw-r--r--hw/xfree86/os-support/bus/ix86Pci.c20
-rw-r--r--hw/xfree86/os-support/shared/stdResource.c2
-rw-r--r--hw/xfree86/os-support/solaris/sun_bios.c4
-rw-r--r--hw/xfree86/os-support/solaris/sun_init.c12
-rw-r--r--hw/xfree86/os-support/solaris/sun_vid.c14
-rw-r--r--hw/xfree86/os-support/sysv/sysv_video.c4
-rw-r--r--hw/xfree86/os-support/xf86_OSlib.h12
-rw-r--r--hw/xfree86/parser/Configint.h4
-rw-r--r--hw/xfree86/parser/Device.c20
-rw-r--r--hw/xfree86/parser/Screen.c24
-rw-r--r--hw/xfree86/parser/read.c2
-rw-r--r--hw/xfree86/utils/xorgcfg/Makefile.am2
-rw-r--r--hw/xfree86/utils/xorgconfig/xorgconfig.c2
-rw-r--r--hw/xfree86/xf4bpp/vgaSolid.c6
-rw-r--r--include/dix-config.h.in8
-rw-r--r--include/dix.h3
-rw-r--r--include/os.h18
-rw-r--r--include/servermd.h9
-rw-r--r--mi/micoord.h3
-rw-r--r--mi/mipointer.c1
-rw-r--r--os/access.c168
-rw-r--r--os/connection.c65
-rw-r--r--os/io.c2
-rw-r--r--os/utils.c1
-rw-r--r--os/xalloc.c2
-rw-r--r--xorg-server.pc.in2
99 files changed, 10630 insertions, 1902 deletions
diff --git a/GL/glx/g_disptab.h b/GL/glx/g_disptab.h
index f9a09ccd6..946e86ba6 100644
--- a/GL/glx/g_disptab.h
+++ b/GL/glx/g_disptab.h
@@ -34,7 +34,6 @@
** version 1.2.1 Specification.
*/
-extern int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc);
extern int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc);
extern int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc);
extern int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc);
@@ -42,7 +41,6 @@ extern int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *p
extern int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
extern int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
-extern int __glXDispSwap_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc);
extern int __glXDispSwap_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc);
extern int __glXDispSwap_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc);
extern int __glXDispSwap_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc);
diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 900a34798..f6e032193 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -73,6 +73,8 @@ GlxSetRenderTables (struct _glapi_table *table)
void
__glXContextDestroy(__GLXcontext *context)
{
+ if (!context->isDirect)
+ __glXDeassociateContext(context);
__glXFlushContextCache();
}
@@ -107,9 +109,10 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
* same as the VisualID.
*/
-int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
- GLXContextID shareList, VisualID visual,
- GLuint screen, GLboolean isDirect)
+static int
+DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
+ GLXContextID shareList, VisualID visual,
+ GLuint screen, GLboolean isDirect)
{
ClientPtr client = cl->client;
VisualPtr pVisual;
@@ -129,8 +132,8 @@ int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
return BadValue;
}
pScreen = screenInfo.screens[screen];
- pGlxScreen = __glXActiveScreens[screen];
-
+ pGlxScreen = glxGetScreen(pScreen);
+
/*
** Check if the visual ID is valid for this screen.
*/
@@ -147,7 +150,7 @@ int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
/*
** Get configuration of the visual. This assumes that the
- ** glXActiveScreens structure contains visual configurations only for the
+ ** glxScreen structure contains visual configurations only for the
** subset of Visuals that are supported by this implementation of the
** OpenGL.
*/
@@ -383,36 +386,6 @@ static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
glxc->isCurrent = GL_TRUE;
}
-/*****************************************************************************/
-/*
-** Make an OpenGL context and drawable current.
-*/
-
-int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
-
- return DoMakeCurrent( cl, req->drawable, req->drawable,
- req->context, req->oldContextTag );
-}
-
-int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
-
- return DoMakeCurrent( cl, req->drawable, req->readdrawable,
- req->context, req->oldContextTag );
-}
-
-int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
-
- return DoMakeCurrent( cl, req->drawable, req->readable,
- req->context, req->oldContextTag );
-}
-
-
/**
* Given a drawable ID, get the associated drawable and / or pixmap.
*
@@ -423,119 +396,94 @@ int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
*
* \param glxc Associated GLX context.
* \param drawId ID of the drawable.
- * \param ppDraw Location to store the pointer to the drawable.
- * \param ppPixmap Location to store the pointer to the pixmap.
* \param client Pointer to the client state.
- * \return Zero is returned on success. Otherwise a GLX / X11 protocol error
- * is returned.
+ * \return the __GLXdrawable is returned on success. Otherwise NULL.
*
* \notes This function will need some modification when support pbuffers
* is added.
*/
-static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId,
- __GLXdrawable **ppGlxDraw,
- __GLXpixmap **ppPixmap,
- ClientPtr client )
+static __GLXdrawable *
+__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
+ int *error)
{
DrawablePtr pDraw;
__GLcontextModes *modes;
__GLXdrawable *pGlxDraw;
- __GLXpixmap *drawPixmap = NULL;
+ VisualID vid;
int rc;
- /* This is the GLX 1.3 case - the client passes in a GLXWindow and
- * we just return the __GLXdrawable. The first time a GLXPixmap
- * comes in, it doesn't have a corresponding __GLXdrawable, so it
- * falls through to the else-case below, but after that it'll have
- * a __GLXdrawable and we'll handle it here. */
+ /* This is the GLX 1.3 case - the client passes in a GLXWindow or
+ * GLXPixmap and we just return the __GLXdrawable. */
pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes);
if (pGlxDraw != NULL) {
if (glxc != NULL && pGlxDraw->modes != glxc->modes) {
client->errorValue = drawId;
- return BadMatch;
+ *error = BadMatch;
+ return NULL;
}
- *ppGlxDraw = pGlxDraw;
- *ppPixmap = pGlxDraw->pGlxPixmap;
- return Success;
+ return pGlxDraw;
}
- /* The drawId wasn't a GLXWindow, so presumably it's a regular X
- * window. In that case, we create a shadow GLXWindow for it on
+ /* The drawId wasn't a GLX drawable, so presumably it's a regular
+ * X window. In that case, we create a shadow GLXWindow for it on
* demand here for pre GLX 1.3 compatibility and use the X Window
* XID as its GLXWindow XID. The client can't explicitly create a
* GLXWindow with the same XID as an X Window, so we wont get any
* resource ID clashes. Effectively, the X Window is now also a
* GLXWindow. */
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
- if (rc == Success) {
- if (pDraw->type == DRAWABLE_WINDOW) {
- VisualID vid = wVisual((WindowPtr)pDraw);
- modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes,
- vid);
- } else {
- /*
- ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
- ** is, but it must first be created with glxCreateGLXPixmap).
- */
- client->errorValue = drawId;
- return __glXError(GLXBadDrawable);
- }
- } else {
- drawPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes);
- if (drawPixmap) {
- pDraw = drawPixmap->pDraw;
- modes = drawPixmap->modes;
- } else {
- /*
- ** Drawable is neither a Window nor a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXError(GLXBadDrawable);
- }
+ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
+ if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
+ client->errorValue = drawId;
+ *error = __glXError(GLXBadDrawable);
+ return NULL;
}
/* If we're not given a context, don't create the __GLXdrawable */
if (glxc == NULL) {
- *ppPixmap = NULL;
- *ppGlxDraw = NULL;
- return Success;
+ *error = __glXError(GLXBadDrawable);
+ return NULL;
}
- /* We're binding an X Window or a GLX Pixmap for the first time
- * and need to create a GLX drawable for it. First check that the
- * drawable screen and fbconfig matches the context ditto. */
+ vid = wVisual((WindowPtr)pDraw);
+ modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, vid);
+
+ /* We're binding an X Window for the first time and need to create
+ * a GLX drawable for it. First check that the drawable screen
+ * and fbconfig matches the context ditto. */
if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) {
client->errorValue = drawId;
- return BadMatch;
+ *error = BadMatch;
+ return NULL;
}
- pGlxDraw =
- glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
- pDraw, drawId, modes);
+ pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
+ pDraw, GLX_DRAWABLE_WINDOW,
+ drawId, modes);
/* since we are creating the drawablePrivate, drawId should be new */
if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
pGlxDraw->destroy (pGlxDraw);
- return BadAlloc;
+ *error = BadAlloc;
+ return NULL;
}
- *ppPixmap = drawPixmap;
- *ppGlxDraw = pGlxDraw;
-
- return 0;
+ return pGlxDraw;
}
+/*****************************************************************************/
+/*
+** Make an OpenGL context and drawable current.
+*/
-int DoMakeCurrent( __GLXclientState *cl,
- GLXDrawable drawId, GLXDrawable readId,
- GLXContextID contextId, GLXContextTag tag )
+static int
+DoMakeCurrent(__GLXclientState *cl,
+ GLXDrawable drawId, GLXDrawable readId,
+ GLXContextID contextId, GLXContextTag tag)
{
ClientPtr client = cl->client;
xGLXMakeCurrentReply reply;
- __GLXpixmap *drawPixmap = NULL;
- __GLXpixmap *readPixmap = NULL;
__GLXcontext *glxc, *prevglxc;
__GLXdrawable *drawPriv = NULL;
__GLXdrawable *readPriv = NULL;
@@ -593,21 +541,13 @@ int DoMakeCurrent( __GLXclientState *cl,
assert( drawId != None );
assert( readId != None );
- status = GetDrawableOrPixmap(glxc, drawId, &drawPriv, &drawPixmap,
- client);
- if ( status != 0 ) {
+ drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
+ if (drawPriv == NULL)
return status;
- }
- if ( readId != drawId ) {
- status = GetDrawableOrPixmap(glxc, readId, &readPriv, &readPixmap,
- client);
- if ( status != 0 ) {
- return status;
- }
- } else {
- readPriv = drawPriv;
- }
+ readPriv = __glXGetDrawable(glxc, readId, client, &status);
+ if (readPriv == NULL)
+ return status;
} else {
/* Switching to no context. Ignore new drawable. */
@@ -669,42 +609,6 @@ int DoMakeCurrent( __GLXclientState *cl,
}
if (prevglxc) {
- if (prevglxc->drawPixmap) {
- if (prevglxc->readPixmap &&
- prevglxc->drawPixmap != prevglxc->readPixmap) {
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- prevglxc->readPixmap->refcnt--;
- if (!prevglxc->readPixmap->idExists &&
- !prevglxc->readPixmap->refcnt) {
- PixmapPtr pPixmap = (PixmapPtr) prevglxc->readPixmap->pDraw;
- /*
- ** The DestroyPixmap routine should decrement the
- ** refcount of the X pixmap and free only if it's zero.
- */
- (*prevglxc->readPixmap->pScreen->DestroyPixmap)(pPixmap);
- xfree(prevglxc->readPixmap);
- }
- }
-
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- prevglxc->drawPixmap->refcnt--;
- if (!prevglxc->drawPixmap->idExists &&
- !prevglxc->drawPixmap->refcnt) {
- PixmapPtr pPixmap = (PixmapPtr) prevglxc->drawPixmap->pDraw;
- /*
- ** The DestroyPixmap routine should decrement the
- ** refcount of the X pixmap and free only if it's zero.
- */
- (*prevglxc->drawPixmap->pScreen->DestroyPixmap)(pPixmap);
- xfree(prevglxc->drawPixmap);
- }
-
- prevglxc->drawPixmap = NULL;
- }
ChangeCurrentContext(cl, glxc, tag);
StopUsingContext(prevglxc);
} else {
@@ -712,16 +616,6 @@ int DoMakeCurrent( __GLXclientState *cl,
}
if (glxc) {
- if (drawPixmap) {
- drawPixmap->refcnt++;
- glxc->drawPixmap = drawPixmap;
- }
-
- if (readPixmap && (readPixmap != drawPixmap)) {
- readPixmap->refcnt++;
- glxc->readPixmap = readPixmap;
- }
-
StartUsingContext(cl, glxc);
reply.contextTag = tag;
} else {
@@ -740,6 +634,30 @@ int DoMakeCurrent( __GLXclientState *cl,
return Success;
}
+int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->drawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->readdrawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->readable,
+ req->context, req->oldContextTag );
+}
+
int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
@@ -912,8 +830,8 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
}
-int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
- GLboolean do_swap)
+static int
+DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
{
ClientPtr client = cl->client;
xGLXGetVisualConfigsReply reply;
@@ -929,7 +847,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
client->errorValue = screen;
return BadValue;
}
- pGlxScreen = __glXActiveScreens[screen];
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
reply.numVisuals = pGlxScreen->numUsableVisuals;
reply.numProps = __GLX_TOTAL_CONFIG;
@@ -938,7 +856,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
- if ( do_swap ) {
+ if (client->swapped) {
__GLX_SWAP_SHORT(&reply.sequenceNumber);
__GLX_SWAP_INT(&reply.length);
__GLX_SWAP_INT(&reply.numVisuals);
@@ -992,7 +910,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
buf[p++] = modes->transparentIndex;
- if ( do_swap ) {
+ if (client->swapped) {
__GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG);
}
WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
@@ -1004,7 +922,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
{
xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
- return DoGetVisualConfigs( cl, req->screen, GL_FALSE );
+ return DoGetVisualConfigs(cl, req->screen);
}
@@ -1100,7 +1018,8 @@ __glXCreateARGBConfig(__GLXscreen *screen)
* is the same, so this routine pulls double duty.
*/
-int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
+static int
+DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
{
ClientPtr client = cl->client;
xGLXGetFBConfigsReply reply;
@@ -1117,7 +1036,7 @@ int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
client->errorValue = screen;
return BadValue;
}
- pGlxScreen = __glXActiveScreens[screen];
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
/* Create the "extra" 32bpp ARGB visual, if not already added.
* XXX This is questionable place to do so! Re-examine this someday.
@@ -1130,7 +1049,7 @@ int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
- if ( do_swap ) {
+ if (client->swapped) {
__GLX_SWAP_SHORT(&reply.sequenceNumber);
__GLX_SWAP_INT(&reply.length);
__GLX_SWAP_INT(&reply.numFBConfigs);
@@ -1185,7 +1104,7 @@ int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex );
WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod );
- if ( do_swap ) {
+ if (client->swapped) {
__GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
}
WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
@@ -1198,41 +1117,32 @@ int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
{
xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
- return DoGetFBConfigs( cl, req->screen, GL_FALSE );
+ return DoGetFBConfigs(cl, req->screen);
}
-
int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
{
xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
- return DoGetFBConfigs( cl, req->screen, GL_FALSE );
+ return DoGetFBConfigs(cl, req->screen);
}
-static int ValidateCreateDrawable(ClientPtr client,
- int screenNum, XID fbconfigId,
- XID drawablId, XID glxDrawableId,
- int type, __GLcontextModes **modes,
- DrawablePtr *ppDraw)
+static int
+DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
+ DrawablePtr pDraw, XID glxDrawableId, int type)
{
- DrawablePtr pDraw;
ScreenPtr pScreen;
VisualPtr pVisual;
__GLXscreen *pGlxScreen;
- int i, rc;
+ __GLXdrawable *pGlxDraw;
+ __GLcontextModes *modes;
+ int i;
LEGAL_NEW_RESOURCE(glxDrawableId, client);
- rc = dixLookupDrawable(&pDraw, drawablId, client, 0, DixUnknownAccess);
- if (rc != Success || pDraw->type != type) {
- client->errorValue = drawablId;
- return type == DRAWABLE_WINDOW ? BadWindow : BadPixmap;
- }
-
/* Check if screen of the fbconfig matches screen of drawable. */
pScreen = pDraw->pScreen;
- if (screenNum != pScreen->myNum) {
+ if (screenNum != pScreen->myNum)
return BadMatch;
- }
/* If this fbconfig has a corresponding VisualRec the number of
* planes must match the drawable depth. */
@@ -1243,56 +1153,59 @@ static int ValidateCreateDrawable(ClientPtr client,
}
/* Get configuration of the visual. */
- pGlxScreen = __glXgetActiveScreen(screenNum);
- *modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
- if (*modes == NULL) {
+ pGlxScreen = glxGetScreen(pScreen);
+ modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
+ if (modes == NULL) {
/* Visual not support on this screen by this OpenGL implementation. */
client->errorValue = fbconfigId;
return BadValue;
}
- *ppDraw = pDraw;
+ /* FIXME: We need to check that the window visual is compatible
+ * with the specified fbconfig. */
+ pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
+ glxDrawableId, modes);
+ if (pGlxDraw == NULL)
+ return BadAlloc;
+
+ if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
+ pGlxDraw->destroy (pGlxDraw);
+ return BadAlloc;
+ }
return Success;
}
-/*
-** Create a GLX Pixmap from an X Pixmap.
-*/
-int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
- GLuint screenNum, XID pixmapId, XID glxPixmapId,
- CARD32 *attribs, CARD32 numAttribs)
+static int
+DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId,
+ XID drawableId, XID glxDrawableId)
{
- ClientPtr client = cl->client;
DrawablePtr pDraw;
- __GLXpixmap *pGlxPixmap;
- __GLcontextModes *modes;
- GLenum target = 0;
- int retval, i;
+ int err;
- retval = ValidateCreateDrawable (client, screenNum, fbconfigId,
- pixmapId, glxPixmapId,
- DRAWABLE_PIXMAP, &modes, &pDraw);
- if (retval != Success)
- return retval;
-
- pGlxPixmap = (__GLXpixmap *) xalloc(sizeof(__GLXpixmap));
- if (!pGlxPixmap) {
- return BadAlloc;
+ err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess);
+ if (err != Success || pDraw->type != DRAWABLE_PIXMAP) {
+ client->errorValue = drawableId;
+ return BadPixmap;
}
- if (!(AddResource(glxPixmapId, __glXPixmapRes, pGlxPixmap))) {
- return BadAlloc;
- }
- pGlxPixmap->pDraw = pDraw;
- pGlxPixmap->pGlxScreen = __glXgetActiveScreen(screenNum);
- pGlxPixmap->pScreen = pDraw->pScreen;
- pGlxPixmap->idExists = True;
-#ifdef XF86DRI
- pGlxPixmap->pDamage = NULL;
-#endif
- pGlxPixmap->refcnt = 0;
- pGlxPixmap->modes = modes;
+ err = DoCreateGLXDrawable(client, screenNum, fbconfigId, pDraw,
+ glxDrawableId, GLX_DRAWABLE_PIXMAP);
+
+ if (err == Success)
+ ((PixmapPtr) pDraw)->refcnt++;
+
+ return err;
+}
+
+static void
+determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs)
+{
+ GLenum target = 0;
+ int i;
+ __GLXdrawable *pGlxDraw;
+
+ pGlxDraw = LookupIDByType(glxDrawableID, __glXDrawableRes);
for (i = 0; i < numAttribs; i++) {
if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
@@ -1306,63 +1219,74 @@ int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
}
}
}
-
+
if (!target) {
- int w = pDraw->width, h = pDraw->height;
-
+ int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
+
if (h & (h - 1) || w & (w - 1))
target = GL_TEXTURE_RECTANGLE_ARB;
else
target = GL_TEXTURE_2D;
}
- pGlxPixmap->target = target;
-
- /*
- ** Bump the ref count on the X pixmap so it won't disappear.
- */
- ((PixmapPtr) pDraw)->refcnt++;
-
- return Success;
+ pGlxDraw->target = target;
}
int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
- return DoCreateGLXPixmap( cl, req->visual, req->screen,
- req->pixmap, req->glxpixmap, NULL, 0 );
+
+ return DoCreateGLXPixmap(cl->client, req->screen, req->visual,
+ req->pixmap, req->glxpixmap);
}
int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
- return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
- req->pixmap, req->glxpixmap,
- (CARD32*)(req + 1),
- req->numAttribs );
+ int err;
+
+ err = DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
+ req->pixmap, req->glxpixmap);
+ if (err != Success)
+ return err;
+
+ determineTextureTarget(req->glxpixmap,
+ (CARD32*) (req + 1), req->numAttribs);
+
+ return Success;
}
int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateGLXPixmapWithConfigSGIXReq *req =
(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
- return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
- req->pixmap, req->glxpixmap, NULL, 0 );
+
+ return DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
+ req->pixmap, req->glxpixmap);
}
-int DoDestroyPixmap(__GLXclientState *cl, XID glxpixmap)
+static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
{
ClientPtr client = cl->client;
+ __GLXdrawable *pGlxDraw;
/*
- ** Check if it's a valid GLX pixmap.
+ ** Check it's the right type of drawable.
*/
- if (!LookupIDByType(glxpixmap, __glXPixmapRes)) {
- client->errorValue = glxpixmap;
- return __glXError(GLXBadPixmap);
+ pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes);
+ if (pGlxDraw == NULL || pGlxDraw->type != type) {
+ client->errorValue = glxdrawable;
+ switch (type) {
+ case GLX_DRAWABLE_WINDOW:
+ return __glXError(GLXBadWindow);
+ case GLX_DRAWABLE_PIXMAP:
+ return __glXError(GLXBadDrawable);
+ case GLX_DRAWABLE_PBUFFER:
+ return __glXError(GLXBadPbuffer);
+ }
}
- FreeResource(glxpixmap, FALSE);
+ FreeResource(glxdrawable, FALSE);
return Success;
}
@@ -1371,32 +1295,116 @@ int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
- return DoDestroyPixmap(cl, req->glxpixmap);
+ return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
}
int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
- return DoDestroyPixmap(cl, req->glxpixmap);
+ return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
+}
+
+static int
+DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
+ int width, int height, XID glxDrawableId)
+{
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ PixmapPtr pPixmap;
+ int i;
+
+ pScreen = screenInfo.screens[screenNum];
+
+ pVisual = pScreen->visuals;
+ for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+ if (pVisual->vid == fbconfigId)
+ break;
+ }
+ if (i == pScreen->numVisuals)
+ return __glXError(GLXBadFBConfig);
+
+ __glXenterServer(GL_FALSE);
+ pPixmap = (*pScreen->CreatePixmap) (pScreen,
+ width, height, pVisual->nplanes);
+ __glXleaveServer(GL_FALSE);
+
+ return DoCreateGLXDrawable(client, screenNum, fbconfigId,
+ &pPixmap->drawable, glxDrawableId,
+ GLX_DRAWABLE_PBUFFER);
}
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
{
- xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
+ xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
+ CARD32 *attrs;
+ int width, height, i;
- (void) req;
+ attrs = (CARD32 *) (req + 1);
+ width = 0;
+ height = 0;
- return BadRequest;
+ for (i = 0; i < req->numAttribs; i++) {
+ switch (attrs[i * 2]) {
+ case GLX_PBUFFER_WIDTH:
+ width = attrs[i * 2 + 1];
+ break;
+ case GLX_PBUFFER_HEIGHT:
+ height = attrs[i * 2 + 1];
+ break;
+ case GLX_LARGEST_PBUFFER:
+ case GLX_PRESERVED_CONTENTS:
+ /* FIXME: huh... */
+ break;
+ }
+ }
+
+ return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+ width, height, req->pbuffer);
+}
+
+int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
+
+ return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+ req->width, req->height, req->pbuffer);
}
int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
- (void) req;
+ return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
+}
- return BadRequest;
+int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
+
+ return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
+}
+
+static int
+DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
+ int numAttribs, CARD32 *attribs)
+{
+ __GLXdrawable *pGlxDraw;
+ int i;
+
+ pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes);
+ for (i = 0; i < numAttribs; i++) {
+ switch(attribs[i * 2]) {
+ case GLX_EVENT_MASK:
+ /* All we do is to record the event mask so we can send it
+ * back when queried. We never actually clobber the
+ * pbuffers, so we never need to send out the event. */
+ pGlxDraw->eventMask = attribs[i * 2 + 1];
+ break;
+ }
+ }
+
+ return Success;
}
int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
@@ -1404,58 +1412,41 @@ int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
xGLXChangeDrawableAttributesReq *req =
(xGLXChangeDrawableAttributesReq *) pc;
- (void) req;
-
- return BadRequest;
+ return DoChangeDrawableAttributes(cl->client, req->drawable,
+ req->numAttribs, (CARD32 *) (req + 1));
}
-int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
+int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
{
- xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- __GLXdrawable *glxPriv;
- __GLXscreen *screen;
- __GLcontextModes *modes;
- int retval;
-
- retval = ValidateCreateDrawable (client, req->screen, req->fbconfig,
- req->window, req->glxwindow,
- DRAWABLE_WINDOW, &modes, &pDraw);
- if (retval != Success)
- return retval;
+ xGLXChangeDrawableAttributesSGIXReq *req =
+ (xGLXChangeDrawableAttributesSGIXReq *)pc;
- /* FIXME: We need to check that the window visual is compatible
- * with the specified fbconfig. */
+ return DoChangeDrawableAttributes(cl->client, req->drawable,
+ req->numAttribs, (CARD32 *) (req + 1));
+}
- screen = __glXgetActiveScreen(req->screen);
- glxPriv = screen->createDrawable(screen, pDraw, req->glxwindow, modes);
- if (glxPriv == NULL)
- return BadAlloc;
+int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ int err;
- if (!AddResource(req->glxwindow, __glXDrawableRes, glxPriv)) {
- glxPriv->destroy (glxPriv);
- return BadAlloc;
+ err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess);
+ if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
+ client->errorValue = req->window;
+ return BadWindow;
}
- return Success;
+ return DoCreateGLXDrawable(client, req->screen, req->fbconfig,
+ pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
}
int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
- ClientPtr client = cl->client;
-
- /*
- ** Check if it's a valid GLX window.
- */
- if (!LookupIDByType(req->glxwindow, __glXDrawableRes)) {
- client->errorValue = req->glxwindow;
- return __glXError(GLXBadWindow);
- }
- FreeResource(req->glxwindow, FALSE);
- return Success;
+ return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
}
@@ -1474,7 +1465,6 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
XID drawId = req->drawable;
__GLXcontext *glxc = NULL;
__GLXdrawable *pGlxDraw;
- __GLXpixmap *pPixmap;
int error;
if (tag) {
@@ -1499,11 +1489,11 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
}
}
- error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client);
- if (error != Success)
+ pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
+ if (pGlxDraw == NULL)
return error;
- if (pGlxDraw != NULL && pGlxDraw->type == DRAWABLE_WINDOW &&
+ if (pGlxDraw->type == DRAWABLE_WINDOW &&
(*pGlxDraw->swapBuffers)(pGlxDraw) == GL_FALSE)
return __glXError(GLXBadDrawable);
@@ -1511,7 +1501,8 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
}
-int DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
+static int
+DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
{
ClientPtr client = cl->client;
__GLXcontext *ctx;
@@ -1574,8 +1565,8 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
ClientPtr client = cl->client;
- __GLXpixmap *pGlxPixmap;
__GLXcontext *context;
+ __GLXdrawable *pGlxDraw;
GLXDrawable drawId;
int buffer;
int error;
@@ -1592,8 +1583,8 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
if (!context)
return error;
- pGlxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
- if (!pGlxPixmap) {
+ pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
+ if (!pGlxDraw || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
client->errorValue = drawId;
return __glXError(GLXBadPixmap);
}
@@ -1603,14 +1594,14 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
return context->textureFromPixmap->bindTexImage(context,
buffer,
- pGlxPixmap);
+ pGlxDraw);
}
int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
ClientPtr client = cl->client;
- __GLXpixmap *pGlxPixmap;
+ __GLXdrawable *pGlxDraw;
__GLXcontext *context;
GLXDrawable drawId;
int buffer;
@@ -1625,10 +1616,10 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
if (!context)
return error;
- pGlxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
- if (!pGlxPixmap) {
+ pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
+ if (!pGlxDraw || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
client->errorValue = drawId;
- return __glXError(GLXBadDrawable);
+ return error;
}
if (!context->textureFromPixmap)
@@ -1636,7 +1627,7 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
return context->textureFromPixmap->releaseTexImage(context,
buffer,
- pGlxPixmap);
+ pGlxDraw);
}
int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
@@ -1645,7 +1636,6 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
GLXContextTag tag = req->contextTag;
__GLXcontext *glxc = NULL;
__GLXdrawable *pGlxDraw;
- __GLXpixmap *pPixmap;
ClientPtr client = cl->client;
GLXDrawable drawId;
int error;
@@ -1684,12 +1674,12 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
}
}
- error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client);
- if (error != Success)
+ pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
+ if (!pGlxDraw)
return error;
if (pGlxDraw == NULL ||
- pGlxDraw->type != DRAWABLE_WINDOW ||
+ pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
pGlxDraw->copySubBuffer == NULL)
return __glXError(GLXBadDrawable);
@@ -1705,28 +1695,30 @@ static int
DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
{
ClientPtr client = cl->client;
- __GLXpixmap *glxPixmap;
xGLXGetDrawableAttributesReply reply;
- CARD32 attributes[4];
- int numAttribs;
+ __GLXdrawable *pGlxDraw;
+ CARD32 attributes[6];
+ int numAttribs, error;
- glxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
- if (!glxPixmap) {
+ pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
+ if (!pGlxDraw) {
client->errorValue = drawId;
- return __glXError(GLXBadPixmap);
+ return error;
}
- numAttribs = 2;
+ numAttribs = 3;
reply.length = numAttribs << 1;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
reply.numAttribs = numAttribs;
attributes[0] = GLX_TEXTURE_TARGET_EXT;
- attributes[1] = glxPixmap->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
+ attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
GLX_TEXTURE_RECTANGLE_EXT;
attributes[2] = GLX_Y_INVERTED_EXT;
attributes[3] = GL_FALSE;
+ attributes[4] = GLX_EVENT_MASK;
+ attributes[5] = pGlxDraw->eventMask;
if (client->swapped) {
__glXSwapGetDrawableAttributesReply(client, &reply, attributes);
@@ -1740,22 +1732,18 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
return Success;
}
-int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
+int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
{
- xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *)pc;
- CARD32 *data;
- XID drawable;
-
- data = (CARD32 *) (req + 1);
- drawable = data[0];
+ xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
- return DoGetDrawableAttributes(cl, drawable);
+ return DoGetDrawableAttributes(cl, req->drawable);
}
-int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
+int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
{
- xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
-
+ xGLXGetDrawableAttributesSGIXReq *req =
+ (xGLXGetDrawableAttributesSGIXReq *)pc;
+
return DoGetDrawableAttributes(cl, req->drawable);
}
@@ -1766,7 +1754,10 @@ int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
** client library to send batches of GL rendering commands.
*/
-int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
+/*
+** Execute all the drawing commands in a request.
+*/
+int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
{
xGLXRenderReq *req;
ClientPtr client= cl->client;
@@ -1777,9 +1768,8 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
__GLXcontext *glxc;
__GLX_DECLARE_SWAP_VARIABLES;
-
req = (xGLXRenderReq *) pc;
- if (do_swap) {
+ if (client->swapped) {
__GLX_SWAP_SHORT(&req->length);
__GLX_SWAP_INT(&req->contextTag);
}
@@ -1803,7 +1793,7 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
** Also, each command must be word aligned.
*/
hdr = (__GLXrenderHeader *) pc;
- if (do_swap) {
+ if (client->swapped) {
__GLX_SWAP_SHORT(&hdr->length);
__GLX_SWAP_SHORT(&hdr->opcode);
}
@@ -1815,7 +1805,8 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
*/
err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
proc = (__GLXdispatchRenderProcPtr)
- __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode, do_swap);
+ __glXGetProtocolDecodeFunction(& Render_dispatch_info,
+ opcode, client->swapped);
if ((err < 0) || (proc == NULL)) {
client->errorValue = commandsDone;
@@ -1824,7 +1815,8 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
if (entry.varsize) {
/* variable size command */
- extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE, do_swap);
+ extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE,
+ client->swapped);
if (extra < 0) {
extra = 0;
}
@@ -1857,15 +1849,11 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
return Success;
}
+
/*
-** Execute all the drawing commands in a request.
+** Execute a large rendering request (one that spans multiple X requests).
*/
-int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
-{
- return DoRender(cl, pc, False);
-}
-
-int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
+int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
{
xGLXRenderLargeReq *req;
ClientPtr client= cl->client;
@@ -1875,10 +1863,9 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
int error;
CARD16 opcode;
__GLX_DECLARE_SWAP_VARIABLES;
-
req = (xGLXRenderLargeReq *) pc;
- if (do_swap) {
+ if (client->swapped) {
__GLX_SWAP_SHORT(&req->length);
__GLX_SWAP_INT(&req->contextTag);
__GLX_SWAP_INT(&req->dataBytes);
@@ -1921,7 +1908,7 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
}
hdr = (__GLXrenderLargeHeader *) pc;
- if (do_swap) {
+ if (client->swapped) {
__GLX_SWAP_INT(&hdr->length);
__GLX_SWAP_INT(&hdr->opcode);
}
@@ -1943,7 +1930,8 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
** be computed from its parameters), all the parameters needed
** will be in the 1st request, so it's okay to do this.
*/
- extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE, do_swap);
+ extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE,
+ client->swapped);
if (extra < 0) {
extra = 0;
}
@@ -2043,7 +2031,8 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
opcode = hdr->opcode;
proc = (__GLXdispatchRenderProcPtr)
- __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode, do_swap);
+ __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode,
+ client->swapped);
if (proc == NULL) {
client->errorValue = opcode;
return __glXError(GLXBadLargeRequest);
@@ -2068,14 +2057,6 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
}
}
-/*
-** Execute a large rendering request (one that spans multiple X requests).
-*/
-int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
-{
- return DoRenderLarge(cl, pc, False);
-}
-
extern RESTYPE __glXSwapBarrierRes;
int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -2086,13 +2067,14 @@ int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
int barrier = req->barrier;
DrawablePtr pDraw;
int screen, rc;
+ __GLXscreen *pGlxScreen;
rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixUnknownAccess);
+ pGlxScreen = glxGetScreen(pDraw->pScreen);
if (rc == Success && (pDraw->type == DRAWABLE_WINDOW)) {
screen = pDraw->pScreen->myNum;
- if (__glXSwapBarrierFuncs &&
- __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc) {
- int ret = __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, barrier);
+ if (pGlxScreen->swapBarrierFuncs) {
+ int ret = pGlxScreen->swapBarrierFuncs->bindSwapBarrierFunc(screen, drawable, barrier);
if (ret == Success) {
if (barrier)
/* add source for cleanup when drawable is gone */
@@ -2116,10 +2098,11 @@ int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
(xGLXQueryMaxSwapBarriersSGIXReq *) pc;
xGLXQueryMaxSwapBarriersSGIXReply reply;
int screen = req->screen;
+ __GLXscreen *pGlxScreen;
- if (__glXSwapBarrierFuncs &&
- __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc)
- reply.max = __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc(screen);
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->swapBarrierFuncs)
+ reply.max = pGlxScreen->swapBarrierFuncs->queryMaxSwapBarriersFunc(screen);
else
reply.max = 0;
@@ -2152,11 +2135,12 @@ int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc)
int npipes=0;
int n= 0;
+ __GLXscreen *pGlxScreen;
- if (__glXHyperpipeFuncs &&
- __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc != NULL) {
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->hyperpipeFuncs) {
rdata =
- (__glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc(screen, &npipes, &n));
+ (pGlxScreen->hyperpipeFuncs->queryHyperpipeNetworkFunc(screen, &npipes, &n));
}
length = __GLX_PAD(n) >> 2;
reply.type = X_Reply;
@@ -2189,13 +2173,13 @@ int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc)
int screen = req->screen;
int success = GLX_BAD_HYPERPIPE_SGIX;
int hpId ;
+ __GLXscreen *pGlxScreen;
hpId = req->hpId;
-
- if (__glXHyperpipeFuncs &&
- __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc != NULL) {
- success = __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc(screen, hpId);
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->hyperpipeFuncs) {
+ success = pGlxScreen->hyperpipeFuncs->destroyHyperpipeConfigFunc(screen, hpId);
}
reply.type = X_Reply;
@@ -2227,12 +2211,13 @@ int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
int npipes=0;
int n= 0;
int hpId;
+ __GLXscreen *pGlxScreen;
hpId = req->hpId;
- if (__glXHyperpipeFuncs &&
- __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc != NULL) {
- rdata = __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->hyperpipeFuncs) {
+ rdata = pGlxScreen->hyperpipeFuncs->queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
}
length = __GLX_PAD(n) >> 2;
@@ -2270,14 +2255,15 @@ int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
int npipes=0, networkId;
int hpId=-1;
+ __GLXscreen *pGlxScreen;
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
networkId = (int)req->networkId;
npipes = (int)req->npipes;
rdata = (void *)(req +1);
- if (__glXHyperpipeFuncs &&
- __glXHyperpipeFuncs[screen].hyperpipeConfigFunc != NULL) {
- __glXHyperpipeFuncs[screen].hyperpipeConfigFunc(screen,networkId,
+ if (pGlxScreen->hyperpipeFuncs) {
+ pGlxScreen->hyperpipeFuncs->hyperpipeConfigFunc(screen,networkId,
&hpId, &npipes,
(void *) rdata);
}
@@ -2366,7 +2352,7 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
return BadValue;
}
- ptr = __glXActiveScreens[screen]->GLXextensions;
+ ptr = glxGetScreen(screenInfo.screens[screen])->GLXextensions;
n = strlen(ptr) + 1;
length = __GLX_PAD(n) >> 2;
@@ -2402,6 +2388,7 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
size_t n, length;
const char *ptr;
char *buf;
+ __GLXscreen *pGlxScreen;
name = req->name;
screen = req->screen;
@@ -2412,15 +2399,17 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
client->errorValue = screen;
return BadValue;
}
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+
switch(name) {
case GLX_VENDOR:
- ptr = __glXActiveScreens[screen]->GLXvendor;
+ ptr = pGlxScreen->GLXvendor;
break;
case GLX_VERSION:
- ptr = __glXActiveScreens[screen]->GLXversion;
+ ptr = pGlxScreen->GLXversion;
break;
case GLX_EXTENSIONS:
- ptr = __glXActiveScreens[screen]->GLXextensions;
+ ptr = pGlxScreen->GLXextensions;
break;
default:
return BadValue;
diff --git a/GL/glx/glxcmdsswap.c b/GL/glx/glxcmdsswap.c
index 12bc03037..7f17c263b 100644
--- a/GL/glx/glxcmdsswap.c
+++ b/GL/glx/glxcmdsswap.c
@@ -77,8 +77,7 @@ int __glXDispSwap_CreateContext(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->screen);
__GLX_SWAP_INT(&req->shareList);
- return DoCreateContext( cl, req->context, req->shareList, req->visual,
- req->screen, req->isDirect );
+ return __glXDisp_CreateContext(cl, pc);
}
int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
@@ -93,8 +92,7 @@ int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->renderType);
__GLX_SWAP_INT(&req->shareList);
- return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
- req->screen, req->isDirect );
+ return __glXDisp_CreateNewContext(cl, pc);
}
int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -110,8 +108,7 @@ int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->renderType);
__GLX_SWAP_INT(&req->shareList);
- return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
- req->screen, req->isDirect );
+ return __glXDisp_CreateContextWithConfigSGIX(cl, pc);
}
int __glXDispSwap_DestroyContext(__GLXclientState *cl, GLbyte *pc)
@@ -135,8 +132,7 @@ int __glXDispSwap_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->context);
__GLX_SWAP_INT(&req->oldContextTag);
- return DoMakeCurrent( cl, req->drawable, req->drawable,
- req->context, req->oldContextTag );
+ return __glXDisp_MakeCurrent(cl, pc);
}
int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
@@ -150,8 +146,7 @@ int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->context);
__GLX_SWAP_INT(&req->oldContextTag);
- return DoMakeCurrent( cl, req->drawable, req->readdrawable,
- req->context, req->oldContextTag );
+ return __glXDisp_MakeContextCurrent(cl, pc);
}
int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
@@ -165,8 +160,7 @@ int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->context);
__GLX_SWAP_INT(&req->oldContextTag);
- return DoMakeCurrent( cl, req->drawable, req->readable,
- req->context, req->oldContextTag );
+ return __glXDisp_MakeCurrentReadSGI(cl, pc);
}
int __glXDispSwap_IsDirect(__GLXclientState *cl, GLbyte *pc)
@@ -233,7 +227,7 @@ int __glXDispSwap_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_INT(&req->screen);
- return DoGetVisualConfigs( cl, req->screen, GL_TRUE );
+ return __glXDisp_GetVisualConfigs(cl, pc);
}
int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
@@ -242,7 +236,7 @@ int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_INT(&req->screen);
- return DoGetFBConfigs( cl, req->screen, GL_TRUE );
+ return __glXDisp_GetFBConfigs(cl, pc);
}
int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -251,7 +245,7 @@ int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_INT(&req->screen);
- return DoGetFBConfigs( cl, req->screen, GL_TRUE );
+ return __glXDisp_GetFBConfigsSGIX(cl, pc);
}
int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
@@ -265,14 +259,15 @@ int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->pixmap);
__GLX_SWAP_INT(&req->glxpixmap);
- return DoCreateGLXPixmap( cl, req->visual, req->screen,
- req->pixmap, req->glxpixmap, NULL, 0 );
+ return __glXDisp_CreateGLXPixmap(cl, pc);
}
int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
+ CARD32 *attribs;
__GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
__GLX_SWAP_SHORT(&req->length);
__GLX_SWAP_INT(&req->screen);
@@ -280,11 +275,10 @@ int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
__GLX_SWAP_INT(&req->pixmap);
__GLX_SWAP_INT(&req->glxpixmap);
__GLX_SWAP_INT(&req->numAttribs);
+ attribs = (CARD32*)(req + 1);
+ __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
- return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
- req->pixmap, req->glxpixmap,
- (CARD32*)(req + 1),
- req->numAttribs );
+ return __glXDisp_CreatePixmap(cl, pc);
}
int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -299,8 +293,7 @@ int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc
__GLX_SWAP_INT(&req->pixmap);
__GLX_SWAP_INT(&req->glxpixmap);
- return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
- req->pixmap, req->glxpixmap, NULL, 0 );
+ return __glXDisp_CreateGLXPixmapWithConfigSGIX(cl, pc);
}
int __glXDispSwap_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
@@ -328,52 +321,123 @@ int __glXDispSwap_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
int __glXDispSwap_QueryContext(__GLXclientState *cl, GLbyte *pc)
{
xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
- (void) req;
+ __GLX_SWAP_INT(&req->context);
- return BadRequest;
+ return __glXDisp_QueryContext(cl, pc);
}
int __glXDispSwap_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+ CARD32 *attribs;
+
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->fbconfig);
+ __GLX_SWAP_INT(&req->pbuffer);
+ __GLX_SWAP_INT(&req->numAttribs);
+ attribs = (CARD32*)(req + 1);
+ __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
+
+ return __glXDisp_CreatePbuffer(cl, pc);
+}
- (void) req;
+int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->fbconfig);
+ __GLX_SWAP_INT(&req->pbuffer);
+ __GLX_SWAP_INT(&req->width);
+ __GLX_SWAP_INT(&req->height);
- return BadRequest;
+ return __glXDisp_CreateGLXPbufferSGIX(cl, pc);
}
int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) req;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&req->pbuffer);
+
+ return __glXDisp_DestroyPbuffer(cl, pc);
+}
+
+int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) req;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&req->pbuffer);
- return BadRequest;
+ return __glXDisp_DestroyGLXPbufferSGIX(cl, pc);
}
int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
{
xGLXChangeDrawableAttributesReq *req =
(xGLXChangeDrawableAttributesReq *) req;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+ CARD32 *attribs;
+
+ __GLX_SWAP_INT(&req->drawable);
+ __GLX_SWAP_INT(&req->numAttribs);
+ attribs = (CARD32*)(req + 1);
+ __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
+
+ return __glXDisp_ChangeDrawableAttributes(cl, pc);
+}
+
+int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl,
+ GLbyte *pc)
+{
+ xGLXChangeDrawableAttributesSGIXReq *req =
+ (xGLXChangeDrawableAttributesSGIXReq *) req;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+ CARD32 *attribs;
+
+ __GLX_SWAP_INT(&req->drawable);
+ __GLX_SWAP_INT(&req->numAttribs);
+ attribs = (CARD32*)(req + 1);
+ __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
- return BadRequest;
+ return __glXDisp_ChangeDrawableAttributesSGIX(cl, pc);
}
int __glXDispSwap_CreateWindow(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+ CARD32 *attribs;
- (void) req;
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->fbconfig);
+ __GLX_SWAP_INT(&req->window);
+ __GLX_SWAP_INT(&req->glxwindow);
+ __GLX_SWAP_INT(&req->numAttribs);
+ attribs = (CARD32*)(req + 1);
+ __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
- return BadRequest;
+ return __glXDisp_CreateWindow(cl, pc);
}
int __glXDispSwap_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
- (void) req;
+ __GLX_SWAP_INT(&req->glxwindow);
- return BadRequest;
+ return __glXDisp_DestroyWindow(cl, pc);
}
int __glXDispSwap_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
@@ -643,7 +707,7 @@ void __glXSwapGetDrawableAttributesReply(ClientPtr client,
int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc)
{
- return DoRender(cl, pc, True);
+ return __glXDisp_Render(cl, pc);
}
/*
@@ -651,7 +715,7 @@ int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc)
*/
int __glXDispSwap_RenderLarge(__GLXclientState *cl, GLbyte *pc)
{
- return DoRenderLarge(cl, pc, True);
+ return __glXDisp_RenderLarge(cl, pc);
}
/************************************************************************/
diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h
index eb10ee2a8..712264729 100644
--- a/GL/glx/glxcontext.h
+++ b/GL/glx/glxcontext.h
@@ -44,12 +44,12 @@
typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap;
struct __GLXtextureFromPixmap {
- int (*bindTexImage) (__GLXcontext *baseContext,
- int buffer,
- __GLXpixmap *pixmap);
- int (*releaseTexImage) (__GLXcontext *baseContext,
- int buffer,
- __GLXpixmap *pixmap);
+ int (*bindTexImage) (__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap);
+ int (*releaseTexImage) (__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap);
};
@@ -152,12 +152,6 @@ struct __GLXcontext {
GLint selectBufSize; /* number of elements allocated */
/*
- ** Set only if current drawable is a glx pixmap.
- */
- __GLXpixmap *drawPixmap;
- __GLXpixmap *readPixmap;
-
- /*
** The drawable private this context is bound to
*/
__GLXdrawable *drawPriv;
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index b7ecad929..858bbb35b 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -46,22 +46,12 @@
#include <GL/internal/dri_interface.h>
#endif
-typedef struct {
-
- DrawablePtr pDraw;
- __GLcontextModes *modes;
- __GLXscreen *pGlxScreen;
- ScreenPtr pScreen;
- Bool idExists;
- int refcnt;
- GLenum target;
-#ifdef XF86DRI
- DamagePtr pDamage;
- __DRIcontext *pDRICtx;
- GLint texname;
- unsigned long offset;
-#endif
-} __GLXpixmap;
+/* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */
+enum {
+ GLX_DRAWABLE_WINDOW,
+ GLX_DRAWABLE_PIXMAP,
+ GLX_DRAWABLE_PBUFFER
+};
struct __GLXdrawable {
void (*destroy)(__GLXdrawable *private);
@@ -78,12 +68,10 @@ struct __GLXdrawable {
DrawablePtr pDraw;
XID drawId;
- __GLXpixmap *pGlxPixmap;
/*
- ** Either DRAWABLE_PIXMAP or DRAWABLE_WINDOW, copied from pDraw above.
- ** Needed by the resource freer because pDraw might already have been
- ** freed.
+ ** Either GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_WINDOW or
+ ** GLX_DRAWABLE_PBUFFER.
*/
int type;
@@ -105,6 +93,13 @@ struct __GLXdrawable {
** reference count
*/
int refCount;
+
+ GLenum target;
+
+ /*
+ ** Event mask
+ */
+ unsigned long eventMask;
};
#endif /* !__GLX_drawable_h__ */
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index c1f3eb76b..2ded6aa81 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -59,77 +59,55 @@
#include "dispatch.h"
#include "extension_string.h"
+#define containerOf(ptr, type, member) \
+ (type *)( (char *)ptr - offsetof(type,member) )
-#define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string)
-#define STRINGIFY_ARG(contents) #contents
-
-typedef struct __GLXDRIscreen __GLXDRIscreen;
-typedef struct __GLXDRIcontext __GLXDRIcontext;
+typedef struct __GLXDRIscreen __GLXDRIscreen;
+typedef struct __GLXDRIcontext __GLXDRIcontext;
typedef struct __GLXDRIdrawable __GLXDRIdrawable;
struct __GLXDRIscreen {
__GLXscreen base;
+ __DRIscreen driScreen;
+ void *driver;
- __DRIscreen driScreen;
- void *driver;
+ xf86EnterVTProc *enterVT;
+ xf86LeaveVTProc *leaveVT;
- xf86EnterVTProc *enterVT;
- xf86LeaveVTProc *leaveVT;
+ __DRIcopySubBufferExtension *copySubBuffer;
+ __DRIswapControlExtension *swapControl;
+#ifdef __DRI_TEX_OFFSET
+ __DRItexOffsetExtension *texOffset;
DRITexOffsetStartProcPtr texOffsetStart;
DRITexOffsetFinishProcPtr texOffsetFinish;
- __GLXpixmap* texOffsetOverride[16];
+ __GLXDRIdrawable *texOffsetOverride[16];
GLuint lastTexOffsetOverride;
+#endif
unsigned char glx_enable_bits[__GLX_EXT_BYTES];
};
struct __GLXDRIcontext {
- __GLXcontext base;
-
- __DRIcontext driContext;
+ __GLXcontext base;
+ __DRIcontext driContext;
+ XID hwContextID;
};
struct __GLXDRIdrawable {
- __GLXdrawable base;
-
- __DRIdrawable *driDrawable;
+ __GLXdrawable base;
+ __DRIdrawable driDrawable;
+
+ /* Pulled in from old __GLXpixmap */
+#ifdef __DRI_TEX_OFFSET
+ GLint texname;
+ __GLXDRIcontext *ctx;
+ unsigned long offset;
+ DamagePtr pDamage;
+#endif
};
-/* History:
- * 20021121 - Initial version
- * 20021128 - Added __glXWindowExists() function
- * 20021207 - Added support for dynamic GLX extensions,
- * GLX_SGI_swap_control, GLX_SGI_video_sync,
- * GLX_OML_sync_control, and GLX_MESA_swap_control.
- * Never officially released. Do NOT test against
- * this version. Use 20030317 instead.
- * 20030317 - Added support GLX_SGIX_fbconfig,
- * GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
- * GLX_{ARB,SGIS}_multisample, and
- * GLX_SGIX_visual_select_group.
- * 20030606 - Added support for GLX_SGI_make_current_read.
- * 20030813 - Made support for dynamic extensions multi-head aware.
- * 20030818 - Added support for GLX_MESA_allocate_memory in place of the
- * deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset
- * interfaces.
- * 20031201 - Added support for the first round of DRI interface changes.
- * Do NOT test against this version! It has binary
- * compatibility bugs, use 20040317 instead.
- * 20040317 - Added the 'mode' field to __DRIcontextRec.
- * 20040415 - Added support for bindContext3 and unbindContext3.
- * 20040602 - Add __glXGetDrawableInfo. I though that was there
- * months ago. :(
- * 20050727 - Gut all the old interfaces. This breaks compatability with
- * any DRI driver built to any previous version.
- * 20060314 - Added support for GLX_MESA_copy_sub_buffer.
- */
-
-#define INTERNAL_VERSION 20050727
-
-static const char CREATE_NEW_SCREEN_FUNC[] =
- "__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION);
-
+static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING;
static void
__glXDRIleaveServer(GLboolean rendering)
@@ -138,19 +116,19 @@ __glXDRIleaveServer(GLboolean rendering)
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
__GLXDRIscreen * const screen =
- (__GLXDRIscreen *) __glXgetActiveScreen(i);
+ (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
GLuint lastOverride = screen->lastTexOffsetOverride;
if (lastOverride) {
- __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int j;
for (j = 0; j < lastOverride; j++) {
- __GLXpixmap *pGlxPix = texOffsetOverride[j];
+ __GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
if (pGlxPix && pGlxPix->texname) {
pGlxPix->offset =
- screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw);
+ screen->texOffsetStart((PixmapPtr)pGlxPix->base.pDraw);
}
}
}
@@ -160,23 +138,22 @@ __glXDRIleaveServer(GLboolean rendering)
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
__GLXDRIscreen * const screen =
- (__GLXDRIscreen *) __glXgetActiveScreen(i);
+ (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
GLuint lastOverride = screen->lastTexOffsetOverride;
if (lastOverride) {
- __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int j;
for (j = 0; j < lastOverride; j++) {
- __GLXpixmap *pGlxPix = texOffsetOverride[j];
+ __GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
if (pGlxPix && pGlxPix->texname) {
- screen->driScreen.setTexOffset(pGlxPix->pDRICtx,
- pGlxPix->texname,
- pGlxPix->offset,
- pGlxPix->pDraw->depth,
- ((PixmapPtr)pGlxPix->pDraw)->
- devKind);
+ screen->texOffset->setTexOffset(&pGlxPix->ctx->driContext,
+ pGlxPix->texname,
+ pGlxPix->offset,
+ pGlxPix->base.pDraw->depth,
+ ((PixmapPtr)pGlxPix->base.pDraw)->devKind);
}
}
}
@@ -189,8 +166,8 @@ __glXDRIenterServer(GLboolean rendering)
int i;
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
- __GLXDRIscreen * const screen =
- (__GLXDRIscreen *) __glXgetActiveScreen(i);
+ __GLXDRIscreen * const screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[i]);
if (screen->lastTexOffsetOverride) {
CALL_Flush(GET_DISPATCH(), ());
@@ -201,29 +178,17 @@ __glXDRIenterServer(GLboolean rendering)
DRIWakeupHandler(NULL, 0, NULL);
}
-/**
- * \bug
- * We're jumping through hoops here to get the DRIdrawable which the DRI
- * driver tries to keep to it self... cf. FIXME in \c createDrawable.
- */
static void
-__glXDRIdrawableFoo(__GLXDRIdrawable *draw)
+__glXDRIdrawableDestroy(__GLXdrawable *drawable)
{
- __GLXDRIscreen * const screen =
- (__GLXDRIscreen *) __glXgetActiveScreen(draw->base.pDraw->pScreen->myNum);
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
- draw->driDrawable = (*screen->driScreen.getDrawable)(NULL,
- draw->base.drawId,
- screen->driScreen.private);
-}
+ (*private->driDrawable.destroyDrawable)(&private->driDrawable);
-static void
-__glXDRIdrawableDestroy(__GLXdrawable *private)
-{
-#if 0
- (*glxPriv->driDrawable.destroyDrawable)(NULL,
- glxPriv->driDrawable.private);
-#endif
+ __glXenterServer(GL_FALSE);
+ DRIDestroyDrawable(drawable->pDraw->pScreen,
+ serverClient, drawable->pDraw);
+ __glXleaveServer(GL_FALSE);
xfree(private);
}
@@ -242,10 +207,7 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
- __glXDRIdrawableFoo(private);
-
- (*private->driDrawable->swapBuffers)(NULL,
- private->driDrawable->private);
+ (*private->driDrawable.swapBuffers)(&private->driDrawable);
return TRUE;
}
@@ -255,10 +217,12 @@ static int
__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
{
__GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(baseDrawable->pDraw->pScreen);
- __glXDRIdrawableFoo(draw);
+ if (screen->swapControl)
+ screen->swapControl->setSwapInterval(&draw->driDrawable, interval);
- draw->driDrawable->swap_interval = interval;
return 0;
}
@@ -268,22 +232,26 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
int x, int y, int w, int h)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(basePrivate->pDraw->pScreen);
- __glXDRIdrawableFoo(private);
-
- (*private->driDrawable->copySubBuffer)(NULL,
- private->driDrawable->private,
- x, y, w, h);
+ if (screen->copySubBuffer)
+ screen->copySubBuffer->copySubBuffer(&private->driDrawable,
+ x, y, w, h);
}
static void
__glXDRIcontextDestroy(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ Bool retval;
+
+ context->driContext.destroyContext(&context->driContext);
+
+ __glXenterServer(GL_FALSE);
+ retval = DRIDestroyContext(baseContext->pScreen, context->hwContextID);
+ __glXleaveServer(GL_FALSE);
- context->driContext.destroyContext(NULL,
- context->base.pScreen->myNum,
- context->driContext.private);
__glXContextDestroy(&context->base);
xfree(context);
}
@@ -292,24 +260,20 @@ static int
__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
- return (*context->driContext.bindContext)(NULL,
- context->base.pScreen->myNum,
- baseContext->drawPriv->drawId,
- baseContext->readPriv->drawId,
- &context->driContext);
-}
+ return (*context->driContext.bindContext)(&context->driContext,
+ &draw->driDrawable,
+ &read->driDrawable);
+}
static int
__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- return (*context->driContext.unbindContext)(NULL,
- context->base.pScreen->myNum,
- baseContext->drawPriv->drawId,
- baseContext->readPriv->drawId,
- &context->driContext);
+ return (*context->driContext.unbindContext)(&context->driContext);
}
static int
@@ -331,12 +295,12 @@ static int
__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
- return (*context->driContext.bindContext)(NULL,
- context->base.pScreen->myNum,
- baseContext->drawPriv->drawId,
- baseContext->readPriv->drawId,
- &context->driContext);
+ return (*context->driContext.bindContext)(&context->driContext,
+ &draw->driDrawable,
+ &read->driDrawable);
}
static void
@@ -370,15 +334,17 @@ glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
static int
__glXDRIbindTexImage(__GLXcontext *baseContext,
int buffer,
- __GLXpixmap *glxPixmap)
+ __GLXdrawable *glxPixmap)
{
RegionPtr pRegion = NULL;
PixmapPtr pixmap;
int bpp, override = 0, texname;
GLenum format, type;
- ScreenPtr pScreen = glxPixmap->pScreen;
+ ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
+ __GLXDRIdrawable *driDraw =
+ containerOf(glxPixmap, __GLXDRIdrawable, base);
__GLXDRIscreen * const screen =
- (__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
+ (__GLXDRIscreen *) glxGetScreen(pScreen);
CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
GL_TEXTURE_BINDING_2D :
@@ -390,12 +356,12 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
pixmap = (PixmapPtr) glxPixmap->pDraw;
- if (screen->texOffsetStart && screen->driScreen.setTexOffset) {
- __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ if (screen->texOffsetStart && screen->texOffset) {
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int i, firstEmpty = 16;
for (i = 0; i < 16; i++) {
- if (texOffsetOverride[i] == glxPixmap)
+ if (texOffsetOverride[i] == driDraw)
goto alreadyin;
if (firstEmpty == 16 && !texOffsetOverride[i])
@@ -410,36 +376,37 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
if (firstEmpty >= screen->lastTexOffsetOverride)
screen->lastTexOffsetOverride = firstEmpty + 1;
- texOffsetOverride[firstEmpty] = glxPixmap;
+ texOffsetOverride[firstEmpty] = driDraw;
alreadyin:
override = 1;
- glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext;
+ driDraw->ctx = (__GLXDRIcontext*)baseContext;
- if (texname == glxPixmap->texname)
+ if (texname == driDraw->texname)
return Success;
- glxPixmap->texname = texname;
+ driDraw->texname = texname;
- screen->driScreen.setTexOffset(glxPixmap->pDRICtx, texname, 0,
- pixmap->drawable.depth, pixmap->devKind);
+ screen->texOffset->setTexOffset(&driDraw->ctx->driContext, texname, 0,
+ pixmap->drawable.depth,
+ pixmap->devKind);
}
nooverride:
- if (!glxPixmap->pDamage) {
+ if (!driDraw->pDamage) {
if (!override) {
- glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
- TRUE, pScreen, NULL);
- if (!glxPixmap->pDamage)
+ driDraw->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+ TRUE, pScreen, NULL);
+ if (!driDraw->pDamage)
return BadAlloc;
- DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
+ DamageRegister ((DrawablePtr) pixmap, driDraw->pDamage);
}
pRegion = NULL;
} else {
- pRegion = DamageRegion(glxPixmap->pDamage);
+ pRegion = DamageRegion(driDraw->pDamage);
if (REGION_NIL(pRegion))
return Success;
}
@@ -518,7 +485,7 @@ nooverride:
}
if (!override)
- DamageEmpty(glxPixmap->pDamage);
+ DamageEmpty(driDraw->pDamage);
return Success;
}
@@ -526,19 +493,21 @@ nooverride:
static int
__glXDRIreleaseTexImage(__GLXcontext *baseContext,
int buffer,
- __GLXpixmap *pixmap)
+ __GLXdrawable *pixmap)
{
- ScreenPtr pScreen = pixmap->pScreen;
+ ScreenPtr pScreen = pixmap->pDraw->pScreen;
+ __GLXDRIdrawable *driDraw =
+ containerOf(pixmap, __GLXDRIdrawable, base);
__GLXDRIscreen * const screen =
- (__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
+ (__GLXDRIscreen *) glxGetScreen(pScreen);
GLuint lastOverride = screen->lastTexOffsetOverride;
if (lastOverride) {
- __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int i;
for (i = 0; i < lastOverride; i++) {
- if (texOffsetOverride[i] == pixmap) {
+ if (texOffsetOverride[i] == driDraw) {
if (screen->texOffsetFinish)
screen->texOffsetFinish((PixmapPtr)pixmap->pDraw);
@@ -575,9 +544,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen)
{
__GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
- screen->driScreen.destroyScreen(NULL,
- screen->base.pScreen->myNum,
- screen->driScreen.private);
+ screen->driScreen.destroyScreen(&screen->driScreen);
dlclose(screen->driver);
@@ -593,13 +560,18 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
{
__GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
__GLXDRIcontext *context, *shareContext;
- void *sharePrivate;
+ VisualPtr visual;
+ int i;
+ GLboolean retval;
+ __DRIcontext *driShare;
+ drm_context_t hwContext;
+ ScreenPtr pScreen = baseScreen->pScreen;
shareContext = (__GLXDRIcontext *) baseShareContext;
if (shareContext)
- sharePrivate = shareContext->driContext.private;
+ driShare = &shareContext->driContext;
else
- sharePrivate = NULL;
+ driShare = NULL;
context = xalloc(sizeof *context);
if (context == NULL)
@@ -614,25 +586,43 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
context->base.pScreen = screen->base.pScreen;
context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+ /* Find the requested X visual */
+ visual = pScreen->visuals;
+ for (i = 0; i < pScreen->numVisuals; i++, visual++)
+ if (visual->vid == modes->visualID)
+ break;
+ if (i == pScreen->numVisuals)
+ return GL_FALSE;
+
+ context->hwContextID = FakeClientID(0);
+
+ __glXenterServer(GL_FALSE);
+ retval = DRICreateContext(baseScreen->pScreen, visual,
+ context->hwContextID, &hwContext);
+ __glXleaveServer(GL_FALSE);
context->driContext.private =
- screen->driScreen.createNewContext(NULL, modes,
+ screen->driScreen.createNewContext(&screen->driScreen,
+ modes,
0, /* render type */
- sharePrivate,
+ driShare,
+ hwContext,
&context->driContext);
- context->driContext.mode = modes;
-
return &context->base;
}
static __GLXdrawable *
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
DrawablePtr pDraw,
+ int type,
XID drawId,
__GLcontextModes *modes)
{
+ __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
__GLXDRIdrawable *private;
+ GLboolean retval;
+ drm_drawable_t hwDrawable;
private = xalloc(sizeof *private);
if (private == NULL)
@@ -640,7 +630,8 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
memset(private, 0, sizeof *private);
- if (!__glXDrawableInit(&private->base, screen, pDraw, drawId, modes)) {
+ if (!__glXDrawableInit(&private->base, screen,
+ pDraw, type, drawId, modes)) {
xfree(private);
return NULL;
}
@@ -650,21 +641,19 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
-#if 0
- /* FIXME: It would only be natural that we called
- * driScreen->createNewDrawable here but the DRI drivers manage
- * them a little oddly. FIXME: describe this better.*/
+ __glXenterServer(GL_FALSE);
+ retval = DRICreateDrawable(screen->pScreen, serverClient,
+ pDraw, &hwDrawable);
+ __glXleaveServer(GL_FALSE);
/* The last argument is 'attrs', which is used with pbuffers which
* we currently don't support. */
- glxPriv->driDrawable.private =
- (screen->driScreen.createNewDrawable)(NULL, modes,
- drawId,
- &glxPriv->driDrawable,
- 0,
- NULL);
-#endif
+ private->driDrawable.private =
+ (driScreen->driScreen.createNewDrawable)(&driScreen->driScreen,
+ modes,
+ &private->driDrawable,
+ hwDrawable, 0, NULL);
return &private->base;
}
@@ -727,161 +716,28 @@ filter_modes(__GLcontextModes **server_modes,
}
-static void
-enable_glx_extension(void *psc, const char *ext_name)
-{
- __GLXDRIscreen * const screen = (__GLXDRIscreen *) psc;
-
- __glXEnableExtension(screen->glx_enable_bits, ext_name);
-}
-
-
-static __DRIfuncPtr getProcAddress(const char *proc_name)
-{
- if (strcmp(proc_name, "glxEnableExtension") == 0) {
- return (__DRIfuncPtr) enable_glx_extension;
- }
-
- return NULL;
-}
-
-static __DRIscreen *findScreen(__DRInativeDisplay *dpy, int scrn)
-{
- __GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(scrn);
-
- return &screen->driScreen;
-}
-
-static GLboolean windowExists(__DRInativeDisplay *dpy, __DRIid draw)
-{
- DrawablePtr pDrawable = (DrawablePtr) LookupIDByType(draw, RT_WINDOW);
- int unused;
- drm_clip_rect_t *pRects;
-
- return pDrawable ? DRIGetDrawableInfo(pDrawable->pScreen, pDrawable,
- (unsigned*)&unused, (unsigned*)&unused,
- &unused, &unused, &unused, &unused,
- &unused, &pRects, &unused, &unused,
- &unused, &pRects)
- : GL_FALSE;
-}
-
-static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
- int configID, void *contextID,
- drm_context_t *hw_context)
-{
- XID fakeID;
- VisualPtr visual;
- int i;
- ScreenPtr pScreen;
- GLboolean retval;
-
- pScreen = screenInfo.screens[screen];
-
- /* Find the requested X visual */
- visual = pScreen->visuals;
- for (i = 0; i < pScreen->numVisuals; i++, visual++)
- if (visual->vid == configID)
- break;
- if (i == pScreen->numVisuals)
- return GL_FALSE;
-
- fakeID = FakeClientID(0);
- *(XID *) contextID = fakeID;
-
- __glXDRIenterServer(GL_FALSE);
- retval = DRICreateContext(pScreen, visual, fakeID, hw_context);
- __glXDRIleaveServer(GL_FALSE);
- return retval;
-}
-
-static GLboolean destroyContext(__DRInativeDisplay *dpy, int screen,
- __DRIid context)
-{
- GLboolean retval;
-
- __glXDRIenterServer(GL_FALSE);
- retval = DRIDestroyContext(screenInfo.screens[screen], context);
- __glXDRIleaveServer(GL_FALSE);
- return retval;
-}
-
-static GLboolean
-createDrawable(__DRInativeDisplay *dpy, int screen,
- __DRIid drawable, drm_drawable_t *hHWDrawable)
-{
- DrawablePtr pDrawable;
- GLboolean retval;
-
- pDrawable = (DrawablePtr) LookupIDByClass(drawable, RC_DRAWABLE);
- if (!pDrawable)
- return GL_FALSE;
-
- __glXDRIenterServer(GL_FALSE);
- retval = DRICreateDrawable(screenInfo.screens[screen], __pGlxClient,
- pDrawable, hHWDrawable);
- __glXDRIleaveServer(GL_FALSE);
- return retval;
-}
-
-static GLboolean
-destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
-{
- DrawablePtr pDrawable;
- GLboolean retval;
-
- pDrawable = (DrawablePtr) LookupIDByClass(drawable, RC_DRAWABLE);
- if (!pDrawable)
- return GL_FALSE;
-
- __glXDRIenterServer(GL_FALSE);
- retval = DRIDestroyDrawable(screenInfo.screens[screen], __pGlxClient,
- pDrawable);
- __glXDRIleaveServer(GL_FALSE);
- return retval;
-}
-
static GLboolean
-getDrawableInfo(__DRInativeDisplay *dpy, int screen,
- __DRIid drawable, unsigned int *index, unsigned int *stamp,
+getDrawableInfo(__DRIdrawable *driDrawable,
+ unsigned int *index, unsigned int *stamp,
int *x, int *y, int *width, int *height,
int *numClipRects, drm_clip_rect_t **ppClipRects,
int *backX, int *backY,
int *numBackClipRects, drm_clip_rect_t **ppBackClipRects)
{
- DrawablePtr pDrawable;
+ __GLXDRIdrawable *drawable = containerOf(driDrawable,
+ __GLXDRIdrawable, driDrawable);
+ ScreenPtr pScreen = drawable->base.pDraw->pScreen;
drm_clip_rect_t *pClipRects, *pBackClipRects;
GLboolean retval;
size_t size;
- pDrawable = (DrawablePtr) LookupIDByClass(drawable, RC_DRAWABLE);
- if (!pDrawable) {
- ErrorF("getDrawableInfo failed to look up window\n");
-
- *index = 0;
- *stamp = 0;
- *x = 0;
- *y = 0;
- *width = 0;
- *height = 0;
- *numClipRects = 0;
- *ppClipRects = NULL;
- *backX = 0;
- *backY = 0;
- *numBackClipRects = 0;
- *ppBackClipRects = NULL;
-
- return GL_FALSE;
- }
-
- __glXDRIenterServer(GL_FALSE);
- retval = DRIGetDrawableInfo(screenInfo.screens[screen],
- pDrawable, index, stamp,
+ __glXenterServer(GL_FALSE);
+ retval = DRIGetDrawableInfo(pScreen, drawable->base.pDraw, index, stamp,
x, y, width, height,
numClipRects, &pClipRects,
backX, backY,
numBackClipRects, &pBackClipRects);
- __glXDRIleaveServer(GL_FALSE);
+ __glXleaveServer(GL_FALSE);
if (*numClipRects > 0) {
size = sizeof (drm_clip_rect_t) * *numClipRects;
@@ -889,7 +745,6 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
/* Clip cliprects to screen dimensions (redirected windows) */
if (*ppClipRects != NULL) {
- ScreenPtr pScreen = screenInfo.screens[screen];
int i, j;
for (i = 0, j = 0; i < *numClipRects; i++) {
@@ -946,25 +801,33 @@ getUST(int64_t *ust)
}
}
+static void __glXReportDamage(__DRIdrawable *driDraw,
+ int x, int y,
+ drm_clip_rect_t *rects, int num_rects,
+ GLboolean front_buffer)
+{
+ __GLXDRIdrawable *drawable =
+ containerOf(driDraw, __GLXDRIdrawable, driDrawable);
+ DrawablePtr pDraw = drawable->base.pDraw;
+ RegionRec region;
+
+ REGION_INIT(pDraw->pScreen, &region, (BoxPtr) rects, num_rects);
+ REGION_TRANSLATE(pScreen, &region, pDraw->x, pDraw->y);
+ DamageDamageRegion(pDraw, &region);
+ REGION_UNINIT(pDraw->pScreen, &region);
+}
+
/* Table of functions that we export to the driver. */
static const __DRIinterfaceMethods interface_methods = {
- getProcAddress,
-
_gl_context_modes_create,
_gl_context_modes_destroy,
-
- findScreen,
- windowExists,
-
- createContext,
- destroyContext,
- createDrawable,
- destroyDrawable,
getDrawableInfo,
getUST,
NULL, /* glXGetMscRateOML, */
+
+ __glXReportDamage,
};
static const char dri_driver_path[] = DRI_DRIVER_PATH;
@@ -972,7 +835,8 @@ static const char dri_driver_path[] = DRI_DRIVER_PATH;
static Bool
glxDRIEnterVT (int index, int flags)
{
- __GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(index);
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[index]);
LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
@@ -987,7 +851,8 @@ glxDRIEnterVT (int index, int flags)
static void
glxDRILeaveVT (int index, int flags)
{
- __GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(index);
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[index]);
LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
@@ -996,6 +861,48 @@ glxDRILeaveVT (int index, int flags)
return (*screen->leaveVT) (index, flags);
}
+static void
+initializeExtensions(__GLXDRIscreen *screen)
+{
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = screen->driScreen.getExtensions(&screen->driScreen);
+ for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_COPY_SUB_BUFFER
+ if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+ screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_MESA_copy_sub_buffer");
+
+ LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+ }
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+ if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+ screen->swapControl = (__DRIswapControlExtension *) extensions[i];
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_SGI_swap_control");
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_MESA_swap_control");
+
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+ }
+#endif
+
+#ifdef __DRI_TEX_OFFSET
+ if (strcmp(extensions[i]->name, __DRI_TEX_OFFSET) == 0) {
+ screen->texOffset = (__DRItexOffsetExtension *) extensions[i];
+ LogMessage(X_INFO, "AIGLX: enabled GLX_texture_from_pixmap with driver support\n");
+ }
+#endif
+ /* Ignore unknown extensions */
+ }
+}
+
+#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314
+
static __GLXscreen *
__glXDRIscreenProbe(ScreenPtr pScreen)
{
@@ -1044,8 +951,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
screen->base.pScreen = pScreen;
__glXInitExtensionEnableBits(screen->glx_enable_bits);
- screen->driScreen.screenConfigs = screen;
-
/* DRI protocol version. */
dri_version.major = XF86DRI_MAJOR_VERSION;
@@ -1170,9 +1075,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
driver_modes = NULL;
screen->driScreen.private =
- (*createNewScreen)(NULL, pScreen->myNum,
+ (*createNewScreen)(pScreen->myNum,
&screen->driScreen,
- screen->base.modes,
&ddx_version,
&dri_version,
&drm_version,
@@ -1191,6 +1095,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
&screen->texOffsetFinish);
+ initializeExtensions(screen);
+
__glXScreenInit(&screen->base, pScreen);
buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index b35175ed2..4d6bfd7c6 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -45,8 +45,6 @@ __GLXcontext *__glXLastContext;
** X resources.
*/
RESTYPE __glXContextRes;
-RESTYPE __glXClientRes;
-RESTYPE __glXPixmapRes;
RESTYPE __glXDrawableRes;
RESTYPE __glXSwapBarrierRes;
@@ -55,11 +53,7 @@ RESTYPE __glXSwapBarrierRes;
*/
xGLXSingleReply __glXReply;
-/*
-** A set of state for each client. The 0th one is unused because client
-** indices start at 1, not 0.
-*/
-static __GLXclientState *__glXClients[MAXCLIENTS + 1];
+static int glxClientPrivateIndex;
/*
** Client that called into GLX dispatch.
@@ -77,29 +71,6 @@ static int __glXDispatch(ClientPtr);
static void ResetExtension(ExtensionEntry* extEntry)
{
__glXFlushContextCache();
- __glXResetScreens();
-}
-
-/*
-** Initialize the per-client context storage.
-*/
-static void ResetClientState(int clientIndex)
-{
- __GLXclientState *cl = __glXClients[clientIndex];
-
- if (cl->returnBuf) xfree(cl->returnBuf);
- if (cl->largeCmdBuf) xfree(cl->largeCmdBuf);
- if (cl->currentContexts) xfree(cl->currentContexts);
- memset(cl, 0, sizeof(__GLXclientState));
- /*
- ** By default, assume that the client supports
- ** GLX major version 1 minor version 0 protocol.
- */
- cl->GLClientmajorVersion = 1;
- cl->GLClientminorVersion = 0;
- if (cl->GLClientextensions)
- xfree(cl->GLClientextensions);
-
}
/*
@@ -130,66 +101,6 @@ static int ContextGone(__GLXcontext* cx, XID id)
}
/*
-** Free a client's state.
-*/
-static int ClientGone(int clientIndex, XID id)
-{
- __GLXcontext *cx;
- __GLXclientState *cl = __glXClients[clientIndex];
- int i;
-
- if (cl) {
- /*
- ** Free all the contexts that are current for this client.
- */
- for (i=0; i < cl->numCurrentContexts; i++) {
- cx = cl->currentContexts[i];
- if (cx) {
- __glXDeassociateContext(cx);
- cx->isCurrent = GL_FALSE;
- if (!cx->idExists) {
- __glXFreeContext(cx);
- }
- }
- }
- /*
- ** Re-initialize the client state structure. Don't free it because
- ** we'll probably get another client with this index and use the struct
- ** again. There is a maximum of MAXCLIENTS of these structures.
- */
- ResetClientState(clientIndex);
- }
-
- return True;
-}
-
-/*
-** Free a GLX Pixmap.
-*/
-static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
-{
- PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
-
- pGlxPixmap->idExists = False;
- if (!pGlxPixmap->refcnt) {
-#ifdef XF86DRI
- if (pGlxPixmap->pDamage) {
- DamageUnregister (pGlxPixmap->pDraw, pGlxPixmap->pDamage);
- DamageDestroy(pGlxPixmap->pDamage);
- }
-#endif
- /*
- ** The DestroyPixmap routine should decrement the refcount and free
- ** only if it's zero.
- */
- (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
- xfree(pGlxPixmap);
- }
-
- return True;
-}
-
-/*
** Destroy routine that gets called when a drawable is freed. A drawable
** contains the ancillary buffers needed for rendering.
*/
@@ -198,24 +109,17 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
__GLXcontext *cx, *cx1;
/*
- ** Use glxPriv->type to figure out what kind of drawable this is. Don't
- ** use glxPriv->pDraw->type because by the time this routine is called,
- ** the pDraw might already have been freed.
+ ** When a drawable is destroyed, notify all context bound to
+ ** it, that there are no longer bound to anything.
*/
- if (glxPriv->type == DRAWABLE_WINDOW) {
- /*
- ** When a window is destroyed, notify all context bound to
- ** it, that there are no longer bound to anything.
- */
- for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
- cx1 = cx->nextDrawPriv;
- cx->pendingState |= __GLX_PENDING_DESTROY;
- }
+ for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
+ cx1 = cx->nextDrawPriv;
+ cx->pendingState |= __GLX_PENDING_DESTROY;
+ }
- for (cx = glxPriv->readGlxc; cx; cx = cx1) {
- cx1 = cx->nextReadPriv;
- cx->pendingState |= __GLX_PENDING_DESTROY;
- }
+ for (cx = glxPriv->readGlxc; cx; cx = cx1) {
+ cx1 = cx->nextReadPriv;
+ cx->pendingState |= __GLX_PENDING_DESTROY;
}
__glXUnrefDrawable(glxPriv);
@@ -260,9 +164,10 @@ extern RESTYPE __glXSwapBarrierRes;
static int SwapBarrierGone(int screen, XID drawable)
{
- if (__glXSwapBarrierFuncs &&
- __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
- __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+ __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+
+ if (pGlxScreen->swapBarrierFuncs) {
+ pGlxScreen->swapBarrierFuncs->bindSwapBarrierFunc(screen, drawable, 0);
}
FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
return True;
@@ -310,22 +215,86 @@ int __glXError(int error)
return __glXErrorBase + error;
}
+__GLXclientState *
+glxGetClient(ClientPtr pClient)
+{
+ return (__GLXclientState *) pClient->devPrivates[glxClientPrivateIndex].ptr;
+}
+
+static void
+glxClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ __GLXclientState *cl = glxGetClient(pClient);
+ __GLXcontext *cx;
+ int i;
+
+ switch (pClient->clientState) {
+ case ClientStateRunning:
+ /*
+ ** By default, assume that the client supports
+ ** GLX major version 1 minor version 0 protocol.
+ */
+ cl->GLClientmajorVersion = 1;
+ cl->GLClientminorVersion = 0;
+ cl->client = pClient;
+ break;
+
+ case ClientStateGone:
+ for (i = 0; i < cl->numCurrentContexts; i++) {
+ cx = cl->currentContexts[i];
+ if (cx) {
+ cx->isCurrent = GL_FALSE;
+ if (!cx->idExists)
+ __glXFreeContext(cx);
+ }
+ }
+
+ if (cl->returnBuf) xfree(cl->returnBuf);
+ if (cl->largeCmdBuf) xfree(cl->largeCmdBuf);
+ if (cl->currentContexts) xfree(cl->currentContexts);
+ if (cl->GLClientextensions) xfree(cl->GLClientextensions);
+ break;
+
+ default:
+ break;
+ }
+}
+
/************************************************************************/
+static __GLXprovider *__glXProviderStack;
+
+void GlxPushProvider(__GLXprovider *provider)
+{
+ provider->next = __glXProviderStack;
+ __glXProviderStack = provider;
+}
+
/*
** Initialize the GLX extension.
*/
void GlxExtensionInit(void)
{
ExtensionEntry *extEntry;
+ ScreenPtr pScreen;
int i;
+ __GLXprovider *p;
__glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
- __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
- __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
__glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
__glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+ glxClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (glxClientPrivateIndex,
+ sizeof (__GLXclientState)))
+ return;
+ if (!AddCallback (&ClientStateCallback, glxClientCallback, 0))
+ return;
+
/*
** Add extension to server extensions.
*/
@@ -344,17 +313,18 @@ void GlxExtensionInit(void)
__glXErrorBase = extEntry->errorBase;
- /*
- ** Initialize table of client state. There is never a client 0.
- */
- for (i = 1; i <= MAXCLIENTS; i++) {
- __glXClients[i] = 0;
- }
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
- /*
- ** Initialize screen specific data.
- */
- __glXInitScreens();
+ for (p = __glXProviderStack; p != NULL; p = p->next) {
+ if (p->screenProbe(pScreen) != NULL) {
+ LogMessage(X_INFO,
+ "GLX: Initialized %s GL provider for screen %d\n",
+ p->name, i);
+ break;
+ }
+ }
+ }
}
/************************************************************************/
@@ -422,11 +392,9 @@ void glxSuspendClients(void)
{
int i;
- for (i = 1; i <= MAXCLIENTS; i++) {
- if (__glXClients[i] == NULL || !__glXClients[i]->inUse)
- continue;
-
- IgnoreClient(__glXClients[i]->client);
+ for (i = 1; i < currentMaxClients; i++) {
+ if (glxGetClient(clients[i])->inUse)
+ IgnoreClient(clients[i]);
}
glxBlockClients = TRUE;
@@ -439,11 +407,9 @@ void glxResumeClients(void)
glxBlockClients = FALSE;
- for (i = 1; i <= MAXCLIENTS; i++) {
- if (__glXClients[i] == NULL || !__glXClients[i]->inUse)
- continue;
-
- AttendClient(__glXClients[i]->client);
+ for (i = 1; i < currentMaxClients; i++) {
+ if (glxGetClient(clients[i])->inUse)
+ AttendClient(clients[i]);
}
__glXleaveServer(GL_FALSE);
@@ -505,29 +471,9 @@ static int __glXDispatch(ClientPtr client)
int retval;
opcode = stuff->glxCode;
- cl = __glXClients[client->index];
- if (!cl) {
- cl = (__GLXclientState *) xalloc(sizeof(__GLXclientState));
- __glXClients[client->index] = cl;
- if (!cl) {
- return BadAlloc;
- }
- memset(cl, 0, sizeof(__GLXclientState));
- }
-
- if (!cl->inUse) {
- /*
- ** This is first request from this client. Associate a resource
- ** with the client so we will be notified when the client dies.
- */
- XID xid = FakeClientID(client->index);
- if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
- return BadAlloc;
- }
- ResetClientState(client->index);
- cl->inUse = GL_TRUE;
- cl->client = client;
- }
+ cl = glxGetClient(client);
+ /* Mark it in use so we suspend it on VT switch. */
+ cl->inUse = TRUE;
/*
** If we're expecting a glXRenderLarge request, this better be one.
diff --git a/GL/glx/glxext.h b/GL/glx/glxext.h
index 6774e4d4c..a81850cef 100644
--- a/GL/glx/glxext.h
+++ b/GL/glx/glxext.h
@@ -71,24 +71,6 @@ extern void __glXClearErrorOccured(void);
extern GLboolean __glXErrorOccured(void);
extern void __glXResetLargeCommandStatus(__GLXclientState*);
-extern int DoMakeCurrent( __GLXclientState *cl, GLXDrawable drawId,
- GLXDrawable readId, GLXContextID contextId, GLXContextTag tag );
-extern int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
- GLboolean do_swap);
-extern int DoGetFBConfigs(__GLXclientState *cl, unsigned screen,
- GLboolean do_swap);
-extern int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
- GLXContextID shareList, VisualID visual, GLuint screen, GLboolean isDirect);
-extern int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
- GLuint screenNum, XID pixmapId, XID glxpixmapId, CARD32 *attribs,
- CARD32 numAttribs);
-extern int DoDestroyPixmap(__GLXclientState *cl, XID glxpixmapId);
-
-extern int DoQueryContext(__GLXclientState *cl, GLXContextID gcId);
-
-extern int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap);
-extern int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap);
-
extern void GlxExtensionInit(void);
extern const char GLServerVersion[];
@@ -106,25 +88,5 @@ extern int GlxInitVisuals(
int preferredVis
);
-typedef struct {
- void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
- void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
- int (* destroyHyperpipeConfigFunc)(int, int);
- void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
-} __GLXHyperpipeExtensionFuncs;
-
-extern void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
-
-extern __GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs;
-
-typedef struct {
- int (* bindSwapBarrierFunc)(int, XID, int);
- int (* queryMaxSwapBarriersFunc)(int);
-} __GLXSwapBarrierExtensionFuncs;
-
-extern void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
-
-extern __GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs;
-
#endif /* _glxext_h_ */
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index 679d55c5d..fd4e57d59 100644
--- a/GL/glx/glxglcore.c
+++ b/GL/glx/glxglcore.c
@@ -118,7 +118,7 @@ __glXMesaDrawableSwapBuffers(__GLXdrawable *base)
static __GLXdrawable *
__glXMesaScreenCreateDrawable(__GLXscreen *screen,
- DrawablePtr pDraw,
+ DrawablePtr pDraw, int type,
XID drawId,
__GLcontextModes *modes)
{
@@ -131,7 +131,8 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen,
memset(glxPriv, 0, sizeof *glxPriv);
- if (!__glXDrawableInit(&glxPriv->base, screen, pDraw, drawId, modes)) {
+ if (!__glXDrawableInit(&glxPriv->base, screen,
+ pDraw, type, drawId, modes)) {
xfree(glxPriv);
return NULL;
}
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 43447a4e4..c6f060b3d 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -45,6 +45,8 @@
#include "glxutil.h"
#include "glxext.h"
+static int glxScreenPrivateIndex;
+
const char GLServerVersion[] = "1.4";
static const char GLServerExtensions[] =
"GL_ARB_depth_texture "
@@ -179,36 +181,25 @@ static char GLXServerExtensions[] =
"GLX_MESA_copy_sub_buffer "
;
-__GLXscreen **__glXActiveScreens;
-
-__GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs = NULL;
-static int __glXNumSwapBarrierFuncs = 0;
-__GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs = NULL;
-static int __glXNumHyperpipeFuncs = 0;
-
-__GLXscreen *__glXgetActiveScreen(int num) {
- return __glXActiveScreens[num];
-}
-
-
/*
** This hook gets called when a window moves or changes size.
*/
-static Bool PositionWindow(WindowPtr pWin, int x, int y)
+static Bool glxPositionWindow(WindowPtr pWin, int x, int y)
{
ScreenPtr pScreen;
__GLXcontext *glxc;
__GLXdrawable *glxPriv;
Bool ret;
+ __GLXscreen *pGlxScreen;
/*
** Call wrapped position window routine
*/
pScreen = pWin->drawable.pScreen;
- pScreen->PositionWindow =
- __glXActiveScreens[pScreen->myNum]->WrappedPositionWindow;
+ pGlxScreen = glxGetScreen(pScreen);
+ pScreen->PositionWindow = pGlxScreen->PositionWindow;
ret = (*pScreen->PositionWindow)(pWin, x, y);
- pScreen->PositionWindow = PositionWindow;
+ pScreen->PositionWindow = glxPositionWindow;
/*
** Tell all contexts rendering into this window that the window size
@@ -259,110 +250,71 @@ static Bool PositionWindow(WindowPtr pWin, int x, int y)
void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs)
{
- if (__glXNumHyperpipeFuncs < screen + 1) {
- __glXHyperpipeFuncs = xrealloc(__glXHyperpipeFuncs,
- (screen+1) * sizeof(__GLXHyperpipeExtensionFuncs));
- __glXNumHyperpipeFuncs = screen + 1;
- }
+ __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
- __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc =
- *funcs->queryHyperpipeNetworkFunc;
- __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc =
- *funcs->queryHyperpipeConfigFunc;
- __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc =
- *funcs->destroyHyperpipeConfigFunc;
- __glXHyperpipeFuncs[screen].hyperpipeConfigFunc =
- *funcs->hyperpipeConfigFunc;
+ pGlxScreen->hyperpipeFuncs = funcs;
}
void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs)
{
- if (__glXNumSwapBarrierFuncs < screen + 1) {
- __glXSwapBarrierFuncs = xrealloc(__glXSwapBarrierFuncs,
- (screen+1) * sizeof(__GLXSwapBarrierExtensionFuncs));
- __glXNumSwapBarrierFuncs = screen + 1;
- }
+ __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
- __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc =
- funcs->bindSwapBarrierFunc;
- __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc =
- funcs->queryMaxSwapBarriersFunc;
+ pGlxScreen->swapBarrierFuncs = funcs;
}
-static __GLXprovider *__glXProviderStack;
-
-void GlxPushProvider(__GLXprovider *provider)
+static Bool
+glxCloseScreen (int index, ScreenPtr pScreen)
{
- provider->next = __glXProviderStack;
- __glXProviderStack = provider;
-}
+ __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
-void __glXScreenInit(__GLXscreen *screen, ScreenPtr pScreen)
-{
- screen->pScreen = pScreen;
- screen->GLextensions = xstrdup(GLServerExtensions);
- screen->GLXvendor = xstrdup(GLXServerVendorName);
- screen->GLXversion = xstrdup(GLXServerVersion);
- screen->GLXextensions = xstrdup(GLXServerExtensions);
+ pScreen->CloseScreen = pGlxScreen->CloseScreen;
+ pScreen->PositionWindow = pGlxScreen->PositionWindow;
- screen->WrappedPositionWindow = pScreen->PositionWindow;
- pScreen->PositionWindow = PositionWindow;
+ pGlxScreen->destroy(pGlxScreen);
- __glXScreenInitVisuals(screen);
+ return pScreen->CloseScreen(index, pScreen);
}
-void
-__glXScreenDestroy(__GLXscreen *screen)
+__GLXscreen *
+glxGetScreen(ScreenPtr pScreen)
{
- xfree(screen->GLXvendor);
- xfree(screen->GLXversion);
- xfree(screen->GLXextensions);
- xfree(screen->GLextensions);
+ return (__GLXscreen *) pScreen->devPrivates[glxScreenPrivateIndex].ptr;
}
-void __glXInitScreens(void)
+void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
{
- GLint i;
- ScreenPtr pScreen;
- __GLXprovider *p;
- size_t size;
+ static int glxGeneration;
- /*
- ** This alloc has to work or else the server might as well core dump.
- */
- size = screenInfo.numScreens * sizeof(__GLXscreen *);
- __glXActiveScreens = xalloc(size);
- memset(__glXActiveScreens, 0, size);
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- pScreen = screenInfo.screens[i];
+ if (glxGeneration != serverGeneration)
+ {
+ glxScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ if (glxScreenPrivateIndex == -1)
+ return;
- for (p = __glXProviderStack; p != NULL; p = p->next) {
- __glXActiveScreens[i] = p->screenProbe(pScreen);
- if (__glXActiveScreens[i] != NULL) {
- LogMessage(X_INFO,
- "GLX: Initialized %s GL provider for screen %d\n",
- p->name, i);
- break;
- }
- }
+ glxGeneration = serverGeneration;
}
-}
-void __glXResetScreens(void)
-{
- int i;
+ glxScreen->pScreen = pScreen;
+ glxScreen->GLextensions = xstrdup(GLServerExtensions);
+ glxScreen->GLXvendor = xstrdup(GLXServerVendorName);
+ glxScreen->GLXversion = xstrdup(GLXServerVersion);
+ glxScreen->GLXextensions = xstrdup(GLXServerExtensions);
+
+ glxScreen->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = glxPositionWindow;
+
+ glxScreen->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = glxCloseScreen;
- for (i = 0; i < screenInfo.numScreens; i++)
- if (__glXActiveScreens[i])
- __glXActiveScreens[i]->destroy(__glXActiveScreens[i]);
+ __glXScreenInitVisuals(glxScreen);
- xfree(__glXActiveScreens);
- xfree(__glXHyperpipeFuncs);
- xfree(__glXSwapBarrierFuncs);
- __glXNumHyperpipeFuncs = 0;
- __glXNumSwapBarrierFuncs = 0;
- __glXHyperpipeFuncs = NULL;
- __glXSwapBarrierFuncs = NULL;
- __glXActiveScreens = NULL;
+ pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) glxScreen;
+}
+
+void __glXScreenDestroy(__GLXscreen *screen)
+{
+ xfree(screen->GLXvendor);
+ xfree(screen->GLXversion);
+ xfree(screen->GLXextensions);
+ xfree(screen->GLextensions);
}
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index bba45572f..7b1bbcd58 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -42,6 +42,21 @@
#include "GL/internal/glcore.h"
+typedef struct {
+ void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
+ void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
+ int (* destroyHyperpipeConfigFunc)(int, int);
+ void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
+} __GLXHyperpipeExtensionFuncs;
+
+typedef struct {
+ int (* bindSwapBarrierFunc)(int, XID, int);
+ int (* queryMaxSwapBarriersFunc)(int);
+} __GLXSwapBarrierExtensionFuncs;
+
+void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
+void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
+
/*
** Screen dependent data. These methods are the interface between the DIX
** and DDX layers of the GLX server extension. The methods provide an
@@ -57,11 +72,15 @@ struct __GLXscreen {
__GLXdrawable *(*createDrawable)(__GLXscreen *context,
DrawablePtr pDraw,
+ int type,
XID drawId,
__GLcontextModes *modes);
int (*swapInterval) (__GLXdrawable *drawable,
int interval);
+ __GLXHyperpipeExtensionFuncs *hyperpipeFuncs;
+ __GLXSwapBarrierExtensionFuncs *swapBarrierFuncs;
+
ScreenPtr pScreen;
/**
@@ -79,18 +98,12 @@ struct __GLXscreen {
char *GLXversion;
char *GLXextensions;
- /*
- ** Things that are not statically set.
- */
- Bool (*WrappedPositionWindow)(WindowPtr pWin, int x, int y);
-
+ Bool (*PositionWindow)(WindowPtr pWin, int x, int y);
+ Bool (*CloseScreen)(int index, ScreenPtr pScreen);
};
void __glXScreenInit(__GLXscreen *screen, ScreenPtr pScreen);
void __glXScreenDestroy(__GLXscreen *screen);
-void __glXInitScreens(void);
-extern void __glXResetScreens(void);
-
#endif /* !__GLX_screens_h__ */
diff --git a/GL/glx/glxserver.h b/GL/glx/glxserver.h
index b6b55927e..45de8e794 100644
--- a/GL/glx/glxserver.h
+++ b/GL/glx/glxserver.h
@@ -90,9 +90,8 @@ typedef XID GLXDrawable;
typedef struct __GLXclientStateRec __GLXclientState;
-extern __GLXscreen **__glXActiveScreens;
-extern GLint __glXNumActiveScreens;
-extern __GLXscreen *__glXgetActiveScreen(int num);
+extern __GLXscreen *glxGetScreen(ScreenPtr pScreen);
+extern __GLXclientState *glxGetClient(ClientPtr pClient);
/************************************************************************/
diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c
index 1f172929f..f531ed954 100644
--- a/GL/glx/glxutil.c
+++ b/GL/glx/glxutil.c
@@ -139,18 +139,15 @@ __glXUnrefDrawable(__GLXdrawable *glxPriv)
GLboolean
__glXDrawableInit(__GLXdrawable *drawable,
- __GLXscreen *screen, DrawablePtr pDraw, XID drawId,
- __GLcontextModes *modes)
+ __GLXscreen *screen, DrawablePtr pDraw, int type,
+ XID drawId, __GLcontextModes *modes)
{
- drawable->type = pDraw->type;
drawable->pDraw = pDraw;
+ drawable->type = type;
drawable->drawId = drawId;
drawable->refCount = 1;
drawable->modes = modes;
-
- /* if not a pixmap, lookup will fail, so pGlxPixmap will be NULL */
- drawable->pGlxPixmap = (__GLXpixmap *)
- LookupIDByType(drawId, __glXPixmapRes);
+ drawable->eventMask = 0;
return GL_TRUE;
}
diff --git a/GL/glx/glxutil.h b/GL/glx/glxutil.h
index 1937ef2cf..6534c3f94 100644
--- a/GL/glx/glxutil.h
+++ b/GL/glx/glxutil.h
@@ -50,7 +50,7 @@ extern void __glXUnrefDrawable(__GLXdrawable *glxPriv);
extern GLboolean __glXDrawableInit(__GLXdrawable *drawable,
__GLXscreen *screen,
- DrawablePtr pDraw, XID drawID,
+ DrawablePtr pDraw, int type, XID drawID,
__GLcontextModes *modes);
/* context helper routines */
diff --git a/GL/glx/glxvisuals.c b/GL/glx/glxvisuals.c
index 0e9bdedec..46b380b3d 100644
--- a/GL/glx/glxvisuals.c
+++ b/GL/glx/glxvisuals.c
@@ -55,6 +55,7 @@
void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+extern Bool noGlxVisualInit;
#include "glcontextmodes.h"
struct ScreenVisualsRec {
@@ -452,14 +453,15 @@ Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
/*
* Setup the visuals supported by this particular screen.
*/
- init_visuals(nvisualp, visualp, defaultVisp,
- *ndepthp, *depthp, *rootDepthp);
+ if (!noGlxVisualInit) {
+ init_visuals(nvisualp, visualp, defaultVisp,
+ *ndepthp, *depthp, *rootDepthp);
+ }
return True;
}
-
/************************************************************************/
diff --git a/GL/glx/indirect_dispatch.h b/GL/glx/indirect_dispatch.h
index 24f4bed43..bb39638fd 100644
--- a/GL/glx/indirect_dispatch.h
+++ b/GL/glx/indirect_dispatch.h
@@ -207,6 +207,8 @@ extern HIDDEN void __glXDisp_TexCoord2iv(GLbyte * pc);
extern HIDDEN void __glXDispSwap_TexCoord2iv(GLbyte * pc);
extern HIDDEN void __glXDisp_CompressedTexImage1DARB(GLbyte * pc);
extern HIDDEN void __glXDispSwap_CompressedTexImage1DARB(GLbyte * pc);
+extern HIDDEN void __glXDisp_Rotated(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_Rotated(GLbyte * pc);
extern HIDDEN int __glXDisp_ReadPixels(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN int __glXDispSwap_ReadPixels(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN void __glXDisp_EdgeFlagv(GLbyte * pc);
@@ -293,8 +295,8 @@ extern HIDDEN void __glXDisp_ClearIndex(GLbyte * pc);
extern HIDDEN void __glXDispSwap_ClearIndex(GLbyte * pc);
extern HIDDEN void __glXDisp_LoadMatrixd(GLbyte * pc);
extern HIDDEN void __glXDispSwap_LoadMatrixd(GLbyte * pc);
-extern HIDDEN void __glXDisp_RasterPos2dv(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_RasterPos2dv(GLbyte * pc);
+extern HIDDEN void __glXDisp_PushMatrix(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_PushMatrix(GLbyte * pc);
extern HIDDEN void __glXDisp_ConvolutionParameterfv(GLbyte * pc);
extern HIDDEN void __glXDispSwap_ConvolutionParameterfv(GLbyte * pc);
extern HIDDEN int __glXDisp_GetTexGendv(struct __GLXclientStateRec *, GLbyte *);
@@ -371,14 +373,16 @@ extern HIDDEN void __glXDisp_ProgramNamedParameter4fvNV(GLbyte * pc);
extern HIDDEN void __glXDispSwap_ProgramNamedParameter4fvNV(GLbyte * pc);
extern HIDDEN void __glXDisp_VertexAttrib4fvARB(GLbyte * pc);
extern HIDDEN void __glXDispSwap_VertexAttrib4fvARB(GLbyte * pc);
+extern HIDDEN int __glXDisp_CreateGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_CreateGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN void __glXDisp_MultiTexCoord1svARB(GLbyte * pc);
extern HIDDEN void __glXDispSwap_MultiTexCoord1svARB(GLbyte * pc);
extern HIDDEN void __glXDisp_EndQueryARB(GLbyte * pc);
extern HIDDEN void __glXDispSwap_EndQueryARB(GLbyte * pc);
extern HIDDEN void __glXDisp_DepthMask(GLbyte * pc);
extern HIDDEN void __glXDispSwap_DepthMask(GLbyte * pc);
-extern HIDDEN void __glXDisp_Rotated(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_Rotated(GLbyte * pc);
+extern HIDDEN void __glXDisp_Color4iv(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_Color4iv(GLbyte * pc);
extern HIDDEN int __glXDisp_GetMaterialiv(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN int __glXDispSwap_GetMaterialiv(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN void __glXDisp_StencilOp(GLbyte * pc);
@@ -619,8 +623,8 @@ extern HIDDEN int __glXDisp_PixelStorei(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN int __glXDispSwap_PixelStorei(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN void __glXDisp_VertexAttrib4usvARB(GLbyte * pc);
extern HIDDEN void __glXDispSwap_VertexAttrib4usvARB(GLbyte * pc);
-extern HIDDEN void __glXDisp_Color4iv(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_Color4iv(GLbyte * pc);
+extern HIDDEN int __glXDisp_DestroyGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_DestroyGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN void __glXDisp_EvalCoord2dv(GLbyte * pc);
extern HIDDEN void __glXDispSwap_EvalCoord2dv(GLbyte * pc);
extern HIDDEN void __glXDisp_VertexAttrib3svARB(GLbyte * pc);
@@ -669,6 +673,8 @@ extern HIDDEN void __glXDisp_Lighti(GLbyte * pc);
extern HIDDEN void __glXDispSwap_Lighti(GLbyte * pc);
extern HIDDEN int __glXDisp_GetFramebufferAttachmentParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN int __glXDispSwap_GetFramebufferAttachmentParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDisp_ChangeDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_ChangeDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
extern HIDDEN void __glXDisp_MultiTexCoord4dvARB(GLbyte * pc);
extern HIDDEN void __glXDispSwap_MultiTexCoord4dvARB(GLbyte * pc);
extern HIDDEN int __glXDisp_CreatePbuffer(struct __GLXclientStateRec *, GLbyte *);
@@ -751,8 +757,8 @@ extern HIDDEN void __glXDisp_PixelTransferf(GLbyte * pc);
extern HIDDEN void __glXDispSwap_PixelTransferf(GLbyte * pc);
extern HIDDEN void __glXDisp_CopyTexImage1D(GLbyte * pc);
extern HIDDEN void __glXDispSwap_CopyTexImage1D(GLbyte * pc);
-extern HIDDEN void __glXDisp_PushMatrix(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_PushMatrix(GLbyte * pc);
+extern HIDDEN void __glXDisp_RasterPos2dv(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_RasterPos2dv(GLbyte * pc);
extern HIDDEN void __glXDisp_Fogiv(GLbyte * pc);
extern HIDDEN void __glXDispSwap_Fogiv(GLbyte * pc);
extern HIDDEN void __glXDisp_TexCoord1dv(GLbyte * pc);
diff --git a/GL/glx/indirect_size_get.c b/GL/glx/indirect_size_get.c
index f29ae474e..928571440 100644
--- a/GL/glx/indirect_size_get.c
+++ b/GL/glx/indirect_size_get.c
@@ -697,6 +697,7 @@ __glGetBooleanv_size(GLenum e)
case GL_MATRIX_INDEX_ARRAY_SIZE_ARB:
case GL_MATRIX_INDEX_ARRAY_TYPE_ARB:
case GL_MATRIX_INDEX_ARRAY_STRIDE_ARB:
+ case GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT:
case GL_POINT_SPRITE_ARB:
/* case GL_POINT_SPRITE_NV:*/
case GL_POINT_SPRITE_R_MODE_NV:
@@ -704,8 +705,11 @@ __glGetBooleanv_size(GLenum e)
case GL_MAX_TEXTURE_COORDS_ARB:
case GL_MAX_TEXTURE_IMAGE_UNITS_ARB:
case GL_DEPTH_BOUNDS_TEST_EXT:
+ case GL_MAX_ARRAY_TEXTURE_LAYERS_EXT:
case GL_STENCIL_TEST_TWO_SIDE_EXT:
case GL_ACTIVE_STENCIL_FACE_EXT:
+ case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
+ case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
case GL_RASTER_POSITION_UNCLIPPED_IBM:
return 1;
case GL_SMOOTH_POINT_SIZE_RANGE:
diff --git a/GL/glx/indirect_table.c b/GL/glx/indirect_table.c
index 9d0383c83..3da1f437c 100644
--- a/GL/glx/indirect_table.c
+++ b/GL/glx/indirect_table.c
@@ -1575,9 +1575,9 @@ static const void *VendorPriv_function_table[104][2] = {
/* [ 92] = 65540 */ {__glXDisp_GetFBConfigsSGIX, __glXDispSwap_GetFBConfigsSGIX},
/* [ 93] = 65541 */ {__glXDisp_CreateContextWithConfigSGIX, __glXDispSwap_CreateContextWithConfigSGIX},
/* [ 94] = 65542 */ {__glXDisp_CreateGLXPixmapWithConfigSGIX, __glXDispSwap_CreateGLXPixmapWithConfigSGIX},
- /* [ 95] = 65543 */ {NULL, NULL},
- /* [ 96] = 65544 */ {NULL, NULL},
- /* [ 97] = 65545 */ {NULL, NULL},
+ /* [ 95] = 65543 */ {__glXDisp_CreateGLXPbufferSGIX, __glXDispSwap_CreateGLXPbufferSGIX},
+ /* [ 96] = 65544 */ {__glXDisp_DestroyGLXPbufferSGIX, __glXDispSwap_DestroyGLXPbufferSGIX},
+ /* [ 97] = 65545 */ {__glXDisp_ChangeDrawableAttributesSGIX, __glXDispSwap_ChangeDrawableAttributesSGIX},
/* [ 98] = 65546 */ {__glXDisp_GetDrawableAttributesSGIX, __glXDispSwap_GetDrawableAttributesSGIX},
/* [ 99] = 65547 */ {NULL, NULL},
/* [ 100] = 65548 */ {NULL, NULL},
diff --git a/Xext/shm.c b/Xext/shm.c
index 56a944be1..db3c2ec90 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -64,6 +64,33 @@ in this Software without prior written authorization from The Open Group.
#include <X11/extensions/shmstr.h>
#include <X11/Xfuncproto.h>
+/* Needed for Solaris cross-zone shared memory extension */
+#ifdef HAVE_SHMCTL64
+#include <sys/ipc_impl.h>
+#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf)
+#define SHMSTAT_TYPE struct shmid_ds64
+#define SHMPERM_TYPE struct ipc_perm64
+#define SHM_PERM(buf) buf.shmx_perm
+#define SHM_SEGSZ(buf) buf.shmx_segsz
+#define SHMPERM_UID(p) p->ipcx_uid
+#define SHMPERM_CUID(p) p->ipcx_cuid
+#define SHMPERM_GID(p) p->ipcx_gid
+#define SHMPERM_CGID(p) p->ipcx_cgid
+#define SHMPERM_MODE(p) p->ipcx_mode
+#define SHMPERM_ZONEID(p) p->ipcx_zoneid
+#else
+#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf)
+#define SHMSTAT_TYPE struct shmid_ds
+#define SHMPERM_TYPE struct ipc_perm
+#define SHM_PERM(buf) buf.shm_perm
+#define SHM_SEGSZ(buf) buf.shm_segsz
+#define SHMPERM_UID(p) p->uid
+#define SHMPERM_CUID(p) p->cuid
+#define SHMPERM_GID(p) p->gid
+#define SHMPERM_CGID(p) p->cgid
+#define SHMPERM_MODE(p) p->mode
+#endif
+
#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
@@ -362,32 +389,57 @@ ProcShmQueryVersion(client)
* using the credentials from the client if available
*/
static int
-shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
{
int uid, gid;
mode_t mask;
+ int uidset = 0, gidset = 0;
+ LocalClientCredRec *lcc;
+
+ if (GetLocalClientCreds(client, &lcc) != -1) {
- if (LocalClientCred(client, &uid, &gid) != -1) {
-
- /* User id 0 always gets access */
- if (uid == 0) {
- return 0;
+ if (lcc->fieldsSet & LCC_UID_SET) {
+ uid = lcc->euid;
+ uidset = 1;
+ }
+ if (lcc->fieldsSet & LCC_GID_SET) {
+ gid = lcc->egid;
+ gidset = 1;
}
- /* Check the owner */
- if (perm->uid == uid || perm->cuid == uid) {
- mask = S_IRUSR;
- if (!readonly) {
- mask |= S_IWUSR;
+
+#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
+ if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1)
+ || (lcc->zoneid != SHMPERM_ZONEID(perm))) {
+ uidset = 0;
+ gidset = 0;
+ }
+#endif
+ FreeLocalClientCreds(lcc);
+
+ if (uidset) {
+ /* User id 0 always gets access */
+ if (uid == 0) {
+ return 0;
+ }
+ /* Check the owner */
+ if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) {
+ mask = S_IRUSR;
+ if (!readonly) {
+ mask |= S_IWUSR;
+ }
+ return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
}
- return (perm->mode & mask) == mask ? 0 : -1;
}
- /* Check the group */
- if (perm->gid == gid || perm->cgid == gid) {
- mask = S_IRGRP;
- if (!readonly) {
- mask |= S_IWGRP;
+
+ if (gidset) {
+ /* Check the group */
+ if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) {
+ mask = S_IRGRP;
+ if (!readonly) {
+ mask |= S_IWGRP;
+ }
+ return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
}
- return (perm->mode & mask) == mask ? 0 : -1;
}
}
/* Otherwise, check everyone else */
@@ -395,14 +447,14 @@ shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
if (!readonly) {
mask |= S_IWOTH;
}
- return (perm->mode & mask) == mask ? 0 : -1;
+ return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
}
static int
ProcShmAttach(client)
register ClientPtr client;
{
- struct shmid_ds buf;
+ SHMSTAT_TYPE buf;
ShmDescPtr shmdesc;
REQUEST(xShmAttachReq);
@@ -431,7 +483,7 @@ ProcShmAttach(client)
shmdesc->addr = shmat(stuff->shmid, 0,
stuff->readOnly ? SHM_RDONLY : 0);
if ((shmdesc->addr == ((char *)-1)) ||
- shmctl(stuff->shmid, IPC_STAT, &buf))
+ SHMSTAT(stuff->shmid, &buf))
{
xfree(shmdesc);
return BadAccess;
@@ -441,7 +493,7 @@ ProcShmAttach(client)
* do manual checking of access rights for the credentials
* of the client */
- if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+ if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) {
shmdt(shmdesc->addr);
xfree(shmdesc);
return BadAccess;
@@ -450,7 +502,7 @@ ProcShmAttach(client)
shmdesc->shmid = stuff->shmid;
shmdesc->refcnt = 1;
shmdesc->writable = !stuff->readOnly;
- shmdesc->size = buf.shm_segsz;
+ shmdesc->size = SHM_SEGSZ(buf);
shmdesc->next = Shmsegs;
Shmsegs = shmdesc;
}
diff --git a/configure.ac b/configure.ac
index 8901faec3..d224185be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,7 +179,7 @@ dnl Checks for library functions.
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
strtol getopt getopt_long vsnprintf walkcontext backtrace \
- getisax])
+ getisax getzoneid shmctl64])
AC_FUNC_ALLOCA
dnl Old HAS_* names used in os/*.c.
AC_CHECK_FUNC([getdtablesize],
@@ -290,6 +290,7 @@ case $host_cpu in
alpha*)
ALPHA_VIDEO=yes
case $host_os in
+ *freebsd*) SYS_LIBS=-lio ;;
*netbsd*) AC_DEFINE(USE_ALPHA_PIO, 1, [NetBSD PIO alpha IO]) ;;
esac
;;
@@ -725,6 +726,7 @@ if test "x$XV" = xyes; then
AC_DEFINE(XV, 1, [Support Xv extension])
AC_DEFINE(XvExtension, 1, [Build Xv extension])
REQUIRED_MODULES="$REQUIRED_MODULES videoproto"
+ PKG_CHECK_MODULES(XV, [xv >= 0.22])
else
XVMC=no
fi
@@ -780,7 +782,7 @@ fi
if test "x$GLX" = xyes && ! test "x$MESA_SOURCE" = x; then
PKG_CHECK_MODULES([XLIB], [x11])
- PKG_CHECK_MODULES([GL], [glproto >= 1.4.8])
+ PKG_CHECK_MODULES([GL], [glproto >= 1.4.9])
AC_SUBST(XLIB_CFLAGS)
AC_DEFINE(GLXEXT, 1, [Build GLX extension])
GLX_LIBS='$(top_builddir)/GL/glx/libglx.la $(top_builddir)/GL/mesa/libGLcore.la'
@@ -1446,6 +1448,7 @@ dnl has it in libc), or if libdl is needed to get it.
case $host_os in
darwin*) ;;
*bsd*) ;;
+ linux*) ;;
*) xorg_bus_ix86pci=yes ;;
esac
;;
@@ -1464,7 +1467,7 @@ dnl has it in libc), or if libdl is needed to get it.
;;
x86_64*|amd64*)
case $host_os in
- darwin*|*bsd*)
+ darwin*|*bsd*|linux*)
;;
*)
xorg_bus_ix86pci="yes"
@@ -1859,6 +1862,13 @@ if test "$KDRIVE" = yes; then
if test "x$XEPHYR" = xauto; then
XEPHYR=$xephyr
fi
+ XEPHYR_DRI=no
+ if test x$XEPHYR = xyes -a x$DRI = xyes; then
+ XEPHYR_DRI=yes
+ fi
+ if test x$XEPHYR_DRI = xyes ; then
+ AC_DEFINE(XEPHYR_DRI,1,[enable DRI extension in xephyr])
+ fi
# Xephyr needs nanosleep() which is in librt on Solaris
AC_CHECK_FUNC([nanosleep], [],
@@ -1878,9 +1888,9 @@ if test "$KDRIVE" = yes; then
KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux'
KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
- KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
+ KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS $XV_CFLAGS"
- KDRIVE_PURE_LIBS="$FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB"
+ KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
case $host_os in
*linux*)
@@ -1892,7 +1902,7 @@ if test "$KDRIVE" = yes; then
KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
- KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS"
+ KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS $XV_LIBS"
# check if we can build Xephyr
PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"])
diff --git a/dix/events.c b/dix/events.c
index 0d82d19f3..bb5b9507b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2365,6 +2365,61 @@ DefineInitialRootWindow(WindowPtr win)
#endif
}
+/**
+ * Update the mouse sprite info when the server switches from a pScreen to another.
+ * Otherwise, the pScreen of the mouse sprite is never updated when we switch
+ * from a pScreen to another. Never updating the pScreen of the mouse sprite
+ * implies that windows that are in pScreen whose pScreen->myNum >0 will never
+ * get pointer events. This is because in CheckMotion(), sprite.hotPhys.pScreen
+ * always points to the first pScreen it has been set by
+ * DefineInitialRootWindow().
+ *
+ * Calling this function is useful for use cases where the server
+ * has more than one pScreen.
+ * This function is similar to DefineInitialRootWindow() but it does not
+ * reset the mouse pointer position.
+ * @param win must be the new pScreen we are switching to.
+ */
+void
+UpdateSpriteForScreen(ScreenPtr pScreen)
+{
+ WindowPtr win = NULL;
+ if (!pScreen)
+ return ;
+ win = WindowTable[pScreen->myNum];
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (pScreen,
+ sprite.current,
+ &sprite.hotLimits,
+ &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.screen = pScreen;
+ }
+#endif
+}
+
/*
* This does not take any shortcuts, and even ignores its argument, since
* it does not happen very often, and one has to walk up the tree since
diff --git a/dix/extension.c b/dix/extension.c
index c81c1a123..b765008e8 100644
--- a/dix/extension.c
+++ b/dix/extension.c
@@ -151,6 +151,8 @@ _X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
char *name;
char **aliases;
+ if (!ext)
+ return FALSE ;
aliases = (char **)xrealloc(ext->aliases,
(ext->num_aliases + 1) * sizeof(char *));
if (!aliases)
diff --git a/exa/exa.c b/exa/exa.c
index 56996c436..3f724e64e 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -73,6 +73,14 @@ exaGetPixmapOffset(PixmapPtr pPix)
(unsigned long)pExaScr->info->memoryBase);
}
+void *
+exaGetPixmapDriverPrivate(PixmapPtr pPix)
+{
+ ExaPixmapPriv(pPix);
+
+ return pExaPixmap->driverPriv;
+}
+
/**
* exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap.
*
@@ -174,9 +182,18 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
static Bool
exaDestroyPixmap (PixmapPtr pPixmap)
{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ExaScreenPriv(pScreen);
+
if (pPixmap->refcnt == 1)
{
ExaPixmapPriv (pPixmap);
+
+ if (pExaPixmap->driverPriv) {
+ pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+ pExaPixmap->driverPriv = NULL;
+ }
+
if (pExaPixmap->area)
{
DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
@@ -220,46 +237,87 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
+ int driver_alloc = 0;
int bpp;
ExaScreenPriv(pScreen);
if (w > 32767 || h > 32767)
return NullPixmap;
- pPixmap = fbCreatePixmap (pScreen, w, h, depth);
+ if (!pExaScr->info->CreatePixmap) {
+ pPixmap = fbCreatePixmap (pScreen, w, h, depth);
+ } else {
+ driver_alloc = 1;
+ pPixmap = fbCreatePixmap(pScreen, 0, 0, depth);
+ }
+
if (!pPixmap)
- return NULL;
+ return NULL;
+
pExaPixmap = ExaGetPixmapPriv(pPixmap);
bpp = pPixmap->drawable.bitsPerPixel;
- /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
- if (!w || !h)
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
- else
- pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
-
- pExaPixmap->area = NULL;
-
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
-
- pPixmap->devPrivate.ptr = NULL;
- pExaPixmap->offscreen = FALSE;
-
- pExaPixmap->fb_ptr = NULL;
- if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
- pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
- else
- pExaPixmap->fb_pitch = w * bpp / 8;
- pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
- pExaScr->info->pixmapPitchAlign);
- pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
+ if (driver_alloc) {
+ size_t paddedWidth, datasize;
+ void *driver_priv;
+
+ paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+ if (paddedWidth / 4 > 32767 || h > 32767)
+ return NullPixmap;
+
+ if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
+ pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
+ else
+ pExaPixmap->fb_pitch = w * bpp / 8;
+ pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
+ pExaScr->info->pixmapPitchAlign);
+ if (paddedWidth < pExaPixmap->fb_pitch)
+ paddedWidth = pExaPixmap->fb_pitch;
+
+ datasize = h * paddedWidth;
+
+ driver_priv = pExaScr->info->CreatePixmap(pScreen, datasize, 0);
+ if (!driver_priv) {
+ fbDestroyPixmap(pPixmap);
+ return NULL;
+ }
- if (pExaPixmap->fb_pitch > 131071) {
- fbDestroyPixmap(pPixmap);
- return NULL;
+ (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
+ paddedWidth, NULL);
+ pExaPixmap->driverPriv = driver_priv;
+ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ pExaPixmap->fb_ptr = NULL;
+ } else {
+ pExaPixmap->driverPriv = NULL;
+ /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
+ if (!w || !h)
+ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ else
+ pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
+
+ pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->sys_pitch = pPixmap->devKind;
+
+ pPixmap->devPrivate.ptr = NULL;
+ pExaPixmap->offscreen = FALSE;
+
+ pExaPixmap->fb_ptr = NULL;
+ if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
+ pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
+ else
+ pExaPixmap->fb_pitch = w * bpp / 8;
+ pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
+ pExaScr->info->pixmapPitchAlign);
+ pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
+
+ if (pExaPixmap->fb_pitch > 131071) {
+ fbDestroyPixmap(pPixmap);
+ return NULL;
+ }
}
+
+ pExaPixmap->area = NULL;
/* Set up damage tracking */
pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE,
@@ -306,6 +364,7 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
{
ExaScreenPrivPtr pExaScr;
ExaPixmapPrivPtr pExaPixmap;
+ Bool ret;
if (!pPixmap)
return FALSE;
@@ -317,6 +376,12 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
+ if (pExaScr->info->ModifyPixmapHeader) {
+ ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
+ bitsPerPixel, devKind, pPixData);
+ if (ret == TRUE)
+ return ret;
+ }
return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, pPixData);
}
@@ -344,7 +409,7 @@ exaPixmapIsOffscreen(PixmapPtr p)
save_ptr = p->devPrivate.ptr;
- if (!save_ptr && pExaPixmap)
+ if (!save_ptr && pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
p->devPrivate.ptr = ExaGetPixmapAddress(p);
if (pExaScr->info->PixmapIsOffscreen)
@@ -394,7 +459,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
Bool offscreen = exaPixmapIsOffscreen(pPixmap);
/* Unhide pixmap pointer */
- if (pPixmap->devPrivate.ptr == NULL) {
+ if (pPixmap->devPrivate.ptr == NULL && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
}
@@ -455,8 +520,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
ExaPixmapPriv (pPixmap);
/* Rehide pixmap pointer if we're doing that. */
- if (pExaPixmap)
- {
+ if (pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
pPixmap->devPrivate.ptr = NULL;
}
@@ -690,22 +754,24 @@ exaDriverInit (ScreenPtr pScreen,
return FALSE;
}
- if (!pScreenInfo->memoryBase) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase must be "
- "non-zero\n", pScreen->myNum);
- return FALSE;
- }
+ if (!pScreenInfo->CreatePixmap) {
+ if (!pScreenInfo->memoryBase) {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase "
+ "must be non-zero\n", pScreen->myNum);
+ return FALSE;
+ }
- if (!pScreenInfo->memorySize) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
- "non-zero\n", pScreen->myNum);
- return FALSE;
- }
+ if (!pScreenInfo->memorySize) {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
+ "non-zero\n", pScreen->myNum);
+ return FALSE;
+ }
- if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must be <= "
- "ExaDriverRec::memorySize\n", pScreen->myNum);
- return FALSE;
+ if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must "
+ "be <= ExaDriverRec::memorySize\n", pScreen->myNum);
+ return FALSE;
+ }
}
if (!pScreenInfo->PrepareSolid) {
@@ -729,36 +795,17 @@ exaDriverInit (ScreenPtr pScreen,
/* If the driver doesn't set any max pitch values, we'll just assume
* that there's a limitation by pixels, and that it's the same as
* maxX.
+ *
+ * We want maxPitchPixels or maxPitchBytes to be set so we can check
+ * pixmaps against the max pitch in exaCreatePixmap() -- it matters
+ * whether a pixmap is rejected because of its pitch or
+ * because of its width.
*/
if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes)
{
pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
}
- /* If set, maxPitchPixels must not be smaller than maxX. */
- if (pScreenInfo->maxPitchPixels &&
- pScreenInfo->maxPitchPixels < pScreenInfo->maxX)
- {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchPixels "
- "is smaller than ExaDriverRec::maxX\n",
- pScreen->myNum);
- return FALSE;
- }
-
- /* If set, maxPitchBytes must not be smaller than maxX * 4.
- * This is to ensure that a 32bpp pixmap with the maximum width
- * can be handled wrt the pitch.
- */
- if (pScreenInfo->maxPitchBytes &&
- pScreenInfo->maxPitchBytes < (pScreenInfo->maxX * 4))
- {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchBytes "
- "doesn't allow a 32bpp pixmap with width equal to "
- "ExaDriverRec::maxX\n",
- pScreen->myNum);
- return FALSE;
- }
-
#ifdef RENDER
ps = GetPictureScreenIfSet(pScreen);
#endif
@@ -829,8 +876,7 @@ exaDriverInit (ScreenPtr pScreen,
/*
* Hookup offscreen pixmaps
*/
- if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- pExaScr->info->offScreenBase < pExaScr->info->memorySize)
+ if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)
{
if (!dixRequestPrivate(exaPixmapPrivateKey, sizeof(ExaPixmapPrivRec))) {
LogMessage(X_WARNING,
@@ -846,21 +892,29 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
- LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
- pScreen->myNum,
- pExaScr->info->memorySize - pExaScr->info->offScreenBase);
+ if (!pExaScr->info->CreatePixmap) {
+ LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
+ pScreen->myNum,
+ pExaScr->info->memorySize - pExaScr->info->offScreenBase);
+ } else {
+ LogMessage(X_INFO, "EXA(%d): Driver allocated offscreen pixmaps\n",
+ pScreen->myNum);
+
+ }
}
else
LogMessage(X_INFO, "EXA(%d): No offscreen pixmaps\n", pScreen->myNum);
- DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
- pExaScr->info->memorySize));
- if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
- if (!exaOffscreenInit (pScreen)) {
- LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
- pScreen->myNum);
- return FALSE;
- }
+ if (!pExaScr->info->CreatePixmap) {
+ DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
+ pExaScr->info->memorySize));
+ if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
+ if (!exaOffscreenInit (pScreen)) {
+ LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
+ pScreen->myNum);
+ return FALSE;
+ }
+ }
}
LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"
diff --git a/exa/exa.h b/exa/exa.h
index 491e6b16b..1ff0518e4 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -39,7 +39,7 @@
#include "fb.h"
#define EXA_VERSION_MAJOR 2
-#define EXA_VERSION_MINOR 3
+#define EXA_VERSION_MINOR 4
#define EXA_VERSION_RELEASE 0
typedef struct _ExaOffscreenArea ExaOffscreenArea;
@@ -702,6 +702,13 @@ typedef struct _ExaDriver {
*/
int maxPitchBytes;
+ /* Hooks to allow driver to its own pixmap memory management */
+ void *(*CreatePixmap)(ScreenPtr pScreen, int size, int align);
+ void (*DestroyPixmap)(ScreenPtr pScreen, void *driverPriv);
+ Bool (*ModifyPixmapHeader)(PixmapPtr pPixmap, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ pointer pPixData);
+
/** @} */
} ExaDriverRec, *ExaDriverPtr;
@@ -726,6 +733,13 @@ typedef struct _ExaDriver {
* (right-to-left, bottom-to-top).
*/
#define EXA_TWO_BITBLT_DIRECTIONS (1 << 2)
+
+/**
+ * EXA_HANDLES_PIXMAPS indicates to EXA that the driver can handle
+ * all pixmap addressing and migration.
+ */
+#define EXA_HANDLES_PIXMAPS (1 << 3)
+
/** @} */
ExaDriverPtr
@@ -773,6 +787,9 @@ exaMoveInPixmap (PixmapPtr pPixmap);
void
exaMoveOutPixmap (PixmapPtr pPixmap);
+void *
+exaGetPixmapDriverPrivate(PixmapPtr p);
+
/**
* Returns TRUE if the given planemask covers all the significant bits in the
* pixel values for pDrawable.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 028d93644..8bbf036e4 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -508,14 +508,6 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
region = RECTS_TO_REGION(pScreen, nbox, rects, CT_YXBANDED);
DEALLOCATE_LOCAL(rects);
-
- if (region) {
- src_off_x -= dst_off_x;
- src_off_y -= dst_off_y;
- dst_off_x = dst_off_y = 0;
- pbox = REGION_RECTS(region);
- nbox = REGION_NUM_RECTS(region);
- }
}
}
@@ -1106,6 +1098,7 @@ exaFillRegionSolid (DrawablePtr pDrawable,
ExaPixmapPriv (pPixmap);
int xoff, yoff;
ExaMigrationRec pixmaps[1];
+ Bool ret = FALSE;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
@@ -1118,12 +1111,12 @@ exaFillRegionSolid (DrawablePtr pDrawable,
if (pExaPixmap->accel_blocked)
{
- goto fallback;
+ goto out;
} else {
exaDoMigration (pixmaps, 1, TRUE);
}
- if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
+ if (exaPixmapIsOffscreen (pPixmap) &&
(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
{
int nbox;
@@ -1141,7 +1134,8 @@ exaFillRegionSolid (DrawablePtr pDrawable,
(*pExaScr->info->DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
- if (pDrawable->width == 1 && pDrawable->height == 1 &&
+ if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
+ pDrawable->width == 1 && pDrawable->height == 1 &&
pDrawable->bitsPerPixel != 24) {
ExaPixmapPriv(pPixmap);
@@ -1160,24 +1154,13 @@ exaFillRegionSolid (DrawablePtr pDrawable,
pRegion);
}
- REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
- return TRUE;
+ ret = TRUE;
}
-fallback:
- if (alu != GXcopy || !EXA_PM_IS_SOLID(pDrawable, planemask)) {
- REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
- return FALSE;
- }
- EXA_FALLBACK(("to %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
- exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+out:
REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
- fbFillRegionSolid (pDrawable, pRegion, 0,
- fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- return TRUE;
+ return ret;
}
/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
@@ -1195,11 +1178,12 @@ exaFillRegionTiled (DrawablePtr pDrawable,
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
- int xoff, yoff, tileXoff, tileYoff;
+ int xoff, yoff;
int tileWidth, tileHeight;
ExaMigrationRec pixmaps[2];
int nbox = REGION_NUM_RECTS (pRegion);
BoxPtr pBox = REGION_RECTS (pRegion);
+ Bool ret = FALSE;
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
@@ -1229,22 +1213,17 @@ exaFillRegionTiled (DrawablePtr pDrawable,
if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
{
- goto fallback;
+ goto out;
} else {
exaDoMigration (pixmaps, 2, TRUE);
}
pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
- if (!pPixmap)
- goto fallback;
-
- if (!exaPixmapIsOffscreen(pTile))
- goto fallback;
+ if (!pPixmap || !exaPixmapIsOffscreen(pTile))
+ goto out;
- if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile,
- &tileXoff, &tileYoff),
- pPixmap, 0, 0, alu, planemask))
+ if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
{
while (nbox--)
{
@@ -1252,7 +1231,8 @@ exaFillRegionTiled (DrawablePtr pDrawable,
int dstY = pBox->y1;
int tileY;
- tileY = (dstY - yoff - pDrawable->y - pPatOrg->y) % tileHeight;
+ modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);
+
while (height > 0) {
int width = pBox->x2 - pBox->x1;
int dstX = pBox->x1;
@@ -1263,16 +1243,17 @@ exaFillRegionTiled (DrawablePtr pDrawable,
h = height;
height -= h;
- tileX = (dstX - xoff - pDrawable->x - pPatOrg->x) % tileWidth;
+ modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
+ tileX);
+
while (width > 0) {
int w = tileWidth - tileX;
if (w > width)
w = width;
width -= w;
- (*pExaScr->info->Copy) (pPixmap,
- tileX + tileXoff, tileY + tileYoff,
- dstX, dstY, w, h);
+ (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
+ w, h);
dstX += w;
tileX = 0;
}
@@ -1283,26 +1264,14 @@ exaFillRegionTiled (DrawablePtr pDrawable,
}
(*pExaScr->info->DoneCopy) (pPixmap);
exaMarkSync(pDrawable->pScreen);
- REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
- return TRUE;
- }
-fallback:
- if (alu != GXcopy || !EXA_PM_IS_SOLID(pDrawable, planemask)) {
- REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
- return FALSE;
+ ret = TRUE;
}
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
- exaDrawableLocation(&pTile->drawable),
- exaDrawableLocation(pDrawable)));
- exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+
+out:
REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
- exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
- fbFillRegionTiled (pDrawable, pRegion, pTile);
- exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- return TRUE;
+ return ret;
}
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index c0e022ca7..7968521c5 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -553,6 +553,9 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
ExaScreenPriv(pScreen);
int i, j;
+ if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
+ return;
+
/* If this debugging flag is set, check each pixmap for whether it is marked
* as clean, and if so, actually check if that's the case. This should help
* catch issues with failing to mark a drawable as dirty. While it will
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index b1023a67e..582ddcaa6 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -192,6 +192,10 @@ typedef struct {
* damage, which may be overreported) of a pixmap's system and FB copies.
*/
RegionRec validSys, validFB;
+ /**
+ * Driver private storage per EXA pixmap
+ */
+ void *driverPriv;
} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
typedef struct _ExaMigrationRec {
diff --git a/fb/fbarc.c b/fb/fbarc.c
index 3f46bd4b2..f89b81c52 100644
--- a/fb/fbarc.c
+++ b/fb/fbarc.c
@@ -71,9 +71,13 @@ fbPolyArc (DrawablePtr pDrawable,
BoxRec box;
int x2, y2;
RegionPtr cclip;
+ int wrapped = 0;
cclip = fbGetCompositeClip (pGC);
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+#ifdef FB_ACCESS_WRAPPER
+ wrapped = 1;
+#endif
while (narcs--)
{
if (miCanZeroArc (parcs))
@@ -96,18 +100,43 @@ fbPolyArc (DrawablePtr pDrawable,
y2 = box.y1 + (int)parcs->height + 1;
box.y2 = y2;
if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
- (RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) )
+ (RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) ) {
+#ifdef FB_ACCESS_WRAPPER
+ if (!wrapped) {
+ fbPrepareAccess (pDrawable);
+ wrapped = 1;
+ }
+#endif
(*arc) (dst, dstStride, dstBpp,
parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff,
pPriv->and, pPriv->xor);
- else
+ } else {
+#ifdef FB_ACCESS_WRAPPER
+ if (wrapped) {
+ fbFinishAccess (pDrawable);
+ wrapped = 0;
+ }
+#endif
miZeroPolyArc(pDrawable, pGC, 1, parcs);
+ }
}
- else
+ else {
+#ifdef FB_ACCESS_WRAPPER
+ if (wrapped) {
+ fbFinishAccess (pDrawable);
+ wrapped = 0;
+ }
+#endif
miPolyArc(pDrawable, pGC, 1, parcs);
+ }
parcs++;
}
- fbFinishAccess (pDrawable);
+#ifdef FB_ACCESS_WRAPPER
+ if (wrapped) {
+ fbFinishAccess (pDrawable);
+ wrapped = 0;
+ }
+#endif
}
else
#endif
diff --git a/fb/fbcmap_mi.c b/fb/fbcmap_mi.c
index 58bcae3aa..188decd4c 100644
--- a/fb/fbcmap_mi.c
+++ b/fb/fbcmap_mi.c
@@ -103,6 +103,14 @@ fbSetVisualTypes (int depth, int visuals, int bitsPerRGB)
return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
}
+Bool
+fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB,
+ Pixel redMask, Pixel greenMask, Pixel blueMask)
+{
+ return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB, -1,
+ redMask, greenMask, blueMask);
+}
+
/*
* Given a list of formats for a screen, create a list
* of visuals and depths for the screen which coorespond to
diff --git a/hw/kdrive/ephyr/GL/internal/dri_interface.h b/hw/kdrive/ephyr/GL/internal/dri_interface.h
new file mode 100644
index 000000000..8d24e311f
--- /dev/null
+++ b/hw/kdrive/ephyr/GL/internal/dri_interface.h
@@ -0,0 +1,517 @@
+/*
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * (C) Copyright IBM Corporation 2004
+ * All Rights Reserved.
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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.
+ */
+
+/**
+ * \file dri_interface.h
+ *
+ * This file contains all the types and functions that define the interface
+ * between a DRI driver and driver loader. Currently, the most common driver
+ * loader is the XFree86 libGL.so. However, other loaders do exist, and in
+ * the future the server-side libglx.a will also be a loader.
+ *
+ * \author Kevin E. Martin <kevin@precisioninsight.com>
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#ifndef DRI_INTERFACE_H
+#define DRI_INTERFACE_H
+
+#include <GL/internal/glcore.h>
+#include <drm.h>
+
+/**
+ * \name DRI interface structures
+ *
+ * The following structures define the interface between the GLX client
+ * side library and the DRI (direct rendering infrastructure).
+ */
+/*@{*/
+typedef struct __DRIdisplayRec __DRIdisplay;
+typedef struct __DRIscreenRec __DRIscreen;
+typedef struct __DRIcontextRec __DRIcontext;
+typedef struct __DRIdrawableRec __DRIdrawable;
+typedef struct __DRIdriverRec __DRIdriver;
+typedef struct __DRIframebufferRec __DRIframebuffer;
+typedef struct __DRIversionRec __DRIversion;
+typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods;
+typedef unsigned long __DRIid;
+typedef void __DRInativeDisplay;
+/*@}*/
+
+
+/**
+ * \name Functions provided by the driver loader.
+ */
+/*@{*/
+/**
+ * Type of a pointer to \c glXGetScreenDriver, as returned by
+ * \c glXGetProcAddress. This function is used to get the name of the DRI
+ * driver for the specified screen of the specified display. The driver
+ * name is typically used with \c glXGetDriverConfig.
+ *
+ * \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig
+ */
+typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum);
+
+/**
+ * Type of a pointer to \c glXGetDriverConfig, as returned by
+ * \c glXGetProcAddress. This function is used to get the XML document
+ * describing the configuration options available for the specified driver.
+ *
+ * \sa glXGetDriverConfig, glXGetProcAddress, glXGetScreenDriver
+ */
+typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName);
+
+/**
+ * Type of a pointer to \c glxEnableExtension, as returned by
+ * \c __DRIinterfaceMethods::getProcAddress. This function is used to enable
+ * a GLX extension on the specified screen.
+ */
+typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name );
+/*@}*/
+
+
+/**
+ * \name Functions and data provided by the driver.
+ */
+/*@{*/
+
+typedef void *(CREATENEWSCREENFUNC)(__DRInativeDisplay *dpy, int scrn,
+ __DRIscreen *psc, const __GLcontextModes * modes,
+ const __DRIversion * ddx_version, const __DRIversion * dri_version,
+ const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
+ void * pSAREA, int fd, int internal_api_version,
+ const __DRIinterfaceMethods * interface,
+ __GLcontextModes ** driver_modes);
+typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC;
+extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727;
+
+
+/**
+ * XML document describing the configuration options supported by the
+ * driver.
+ */
+extern const char __driConfigOptions[];
+
+/*@}*/
+
+
+/**
+ * Stored version of some component (i.e., server-side DRI module, kernel-side
+ * DRM, etc.).
+ *
+ * \todo
+ * There are several data structures that explicitly store a major version,
+ * minor version, and patch level. These structures should be modified to
+ * have a \c __DRIversionRec instead.
+ */
+struct __DRIversionRec {
+ int major; /**< Major version number. */
+ int minor; /**< Minor version number. */
+ int patch; /**< Patch-level. */
+};
+
+
+typedef void (*__DRIfuncPtr)(void);
+
+struct __DRIinterfaceMethodsRec {
+ /**
+ * Get pointer to named function.
+ */
+ __DRIfuncPtr (*getProcAddress)( const char * proc_name );
+
+ /**
+ * Create a list of \c __GLcontextModes structures.
+ */
+ __GLcontextModes * (*createContextModes)(unsigned count,
+ size_t minimum_bytes_per_struct);
+
+ /**
+ * Destroy a list of \c __GLcontextModes structures.
+ *
+ * \todo
+ * Determine if the drivers actually need to call this.
+ */
+ void (*destroyContextModes)( __GLcontextModes * modes );
+
+ /**
+ * Get the \c __DRIscreen for a given display and screen number.
+ */
+ __DRIscreen *(*getScreen)(__DRInativeDisplay *dpy, int screenNum);
+
+
+ /**
+ * \name Client/server protocol functions.
+ *
+ * These functions implement the DRI client/server protocol for
+ * context and drawable operations. Platforms that do not implement
+ * the wire protocol (e.g., EGL) will implement glorified no-op functions.
+ */
+ /*@{*/
+ /**
+ * Determine if the specified window ID still exists.
+ *
+ * \note
+ * Implementations may assume that the driver will only pass an ID into
+ * this function that actually corresponds to a window. On
+ * implementations where windows can only be destroyed by the DRI driver
+ * (e.g., EGL), this function is allowed to always return \c GL_TRUE.
+ */
+ GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw);
+
+ /**
+ * Create the server-side portion of the GL context.
+ */
+ GLboolean (* createContext)( __DRInativeDisplay *dpy, int screenNum,
+ int configID, void * contextID, drm_context_t * hw_context );
+
+ /**
+ * Destroy the server-side portion of the GL context.
+ */
+ GLboolean (* destroyContext)( __DRInativeDisplay *dpy, int screenNum,
+ __DRIid context );
+
+ /**
+ * Create the server-side portion of the drawable.
+ */
+ GLboolean (*createDrawable)( __DRInativeDisplay * ndpy, int screen,
+ __DRIid drawable, drm_drawable_t * hHWDrawable );
+
+ /**
+ * Destroy the server-side portion of the drawable.
+ */
+ GLboolean (*destroyDrawable)( __DRInativeDisplay * ndpy, int screen,
+ __DRIid drawable );
+
+ /**
+ * This function is used to get information about the position, size, and
+ * clip rects of a drawable.
+ */
+ GLboolean (* getDrawableInfo) ( __DRInativeDisplay *dpy, int scrn,
+ __DRIid draw, unsigned int * index, unsigned int * stamp,
+ int * x, int * y, int * width, int * height,
+ int * numClipRects, drm_clip_rect_t ** pClipRects,
+ int * backX, int * backY,
+ int * numBackClipRects, drm_clip_rect_t ** pBackClipRects );
+ /*@}*/
+
+
+ /**
+ * \name Timing related functions.
+ */
+ /*@{*/
+ /**
+ * Get the 64-bit unadjusted system time (UST).
+ */
+ int (*getUST)(int64_t * ust);
+
+ /**
+ * Get the media stream counter (MSC) rate.
+ *
+ * Matching the definition in GLX_OML_sync_control, this function returns
+ * the rate of the "media stream counter". In practical terms, this is
+ * the frame refresh rate of the display.
+ */
+ GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable,
+ int32_t * numerator, int32_t * denominator);
+ /*@}*/
+
+ /**
+ * Reports areas of the given drawable which have been modified by the
+ * driver.
+ *
+ * \param drawable which the drawing was done to.
+ * \param rects rectangles affected, with the drawable origin as the
+ * origin.
+ * \param x X offset of the drawable within the screen (used in the
+ * front_buffer case)
+ * \param y Y offset of the drawable within the screen.
+ * \param front_buffer boolean flag for whether the drawing to the
+ * drawable was actually done directly to the front buffer (instead
+ * of backing storage, for example)
+ */
+ void (*reportDamage)(__DRInativeDisplay * dpy, int screen,
+ __DRIid drawable,
+ int x, int y,
+ drm_clip_rect_t *rects, int num_rects,
+ int front_buffer);
+};
+
+
+/**
+ * Framebuffer information record. Used by libGL to communicate information
+ * about the framebuffer to the driver's \c __driCreateNewScreen function.
+ *
+ * In XFree86, most of this information is derrived from data returned by
+ * calling \c XF86DRIGetDeviceInfo.
+ *
+ * \sa XF86DRIGetDeviceInfo __DRIdisplayRec::createNewScreen
+ * __driUtilCreateNewScreen CallCreateNewScreen
+ *
+ * \bug This structure could be better named.
+ */
+struct __DRIframebufferRec {
+ unsigned char *base; /**< Framebuffer base address in the CPU's
+ * address space. This value is calculated by
+ * calling \c drmMap on the framebuffer handle
+ * returned by \c XF86DRIGetDeviceInfo (or a
+ * similar function).
+ */
+ int size; /**< Framebuffer size, in bytes. */
+ int stride; /**< Number of bytes from one line to the next. */
+ int width; /**< Pixel width of the framebuffer. */
+ int height; /**< Pixel height of the framebuffer. */
+ int dev_priv_size; /**< Size of the driver's dev-priv structure. */
+ void *dev_priv; /**< Pointer to the driver's dev-priv structure. */
+};
+
+
+/**
+ * Screen dependent methods. This structure is initialized during the
+ * \c __DRIdisplayRec::createScreen call.
+ */
+struct __DRIscreenRec {
+ /**
+ * Method to destroy the private DRI screen data.
+ */
+ void (*destroyScreen)(__DRInativeDisplay *dpy, int scrn, void *screenPrivate);
+
+ /**
+ * Method to create the private DRI drawable data and initialize the
+ * drawable dependent methods.
+ */
+ void *(*createNewDrawable)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
+ __DRIid draw, __DRIdrawable *pdraw,
+ int renderType, const int *attrs);
+
+ /**
+ * Method to return a pointer to the DRI drawable data.
+ */
+ __DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
+ void *drawablePrivate);
+
+ /**
+ * Opaque pointer to private per screen direct rendering data. \c NULL
+ * if direct rendering is not supported on this screen. Never
+ * dereferenced in libGL.
+ */
+ void *private;
+
+ /**
+ * Get the number of vertical refreshes since some point in time before
+ * this function was first called (i.e., system start up).
+ *
+ * \since Internal API version 20030317.
+ */
+ int (*getMSC)( void *screenPrivate, int64_t *msc );
+
+ /**
+ * Opaque pointer that points back to the containing
+ * \c __GLXscreenConfigs. This data structure is shared with DRI drivers
+ * but \c __GLXscreenConfigs is not. However, they are needed by some GLX
+ * functions called by DRI drivers.
+ *
+ * \since Internal API version 20030813.
+ */
+ void *screenConfigs;
+
+ /**
+ * Functions associated with MESA_allocate_memory.
+ *
+ * \since Internal API version 20030815.
+ */
+ /*@{*/
+ void *(*allocateMemory)(__DRInativeDisplay *dpy, int scrn, GLsizei size,
+ GLfloat readfreq, GLfloat writefreq,
+ GLfloat priority);
+
+ void (*freeMemory)(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer);
+
+ GLuint (*memoryOffset)(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer);
+ /*@}*/
+
+ /**
+ * Method to create the private DRI context data and initialize the
+ * context dependent methods.
+ *
+ * \since Internal API version 20031201.
+ */
+ void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
+ int render_type,
+ void *sharedPrivate, __DRIcontext *pctx);
+
+ /**
+ * Method to override base texture image with a driver specific 'offset'.
+ * The depth passed in allows e.g. to ignore the alpha channel of texture
+ * images where the non-alpha components don't occupy a whole texel.
+ *
+ * For GLX_EXT_texture_from_pixmap with AIGLX.
+ *
+ * \since Internal API version 20070121.
+ */
+ void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
+ unsigned long long offset, GLint depth, GLuint pitch);
+};
+
+/**
+ * Context dependent methods. This structure is initialized during the
+ * \c __DRIscreenRec::createContext call.
+ */
+struct __DRIcontextRec {
+ /**
+ * Method to destroy the private DRI context data.
+ */
+ void (*destroyContext)(__DRInativeDisplay *dpy, int scrn, void *contextPrivate);
+
+ /**
+ * Opaque pointer to private per context direct rendering data.
+ * \c NULL if direct rendering is not supported on the display or
+ * screen used to create this context. Never dereferenced in libGL.
+ */
+ void *private;
+
+ /**
+ * Pointer to the mode used to create this context.
+ *
+ * \since Internal API version 20040317.
+ */
+ const __GLcontextModes * mode;
+
+ /**
+ * Method to bind a DRI drawable to a DRI graphics context.
+ *
+ * \since Internal API version 20050727.
+ */
+ GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
+ __DRIid read, __DRIcontext *ctx);
+
+ /**
+ * Method to unbind a DRI drawable from a DRI graphics context.
+ *
+ * \since Internal API version 20050727.
+ */
+ GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
+ __DRIid read, __DRIcontext *ctx);
+};
+
+/**
+ * Drawable dependent methods. This structure is initialized during the
+ * \c __DRIscreenRec::createDrawable call. \c createDrawable is not called
+ * by libGL at this time. It's currently used via the dri_util.c utility code
+ * instead.
+ */
+struct __DRIdrawableRec {
+ /**
+ * Method to destroy the private DRI drawable data.
+ */
+ void (*destroyDrawable)(__DRInativeDisplay *dpy, void *drawablePrivate);
+
+ /**
+ * Method to swap the front and back buffers.
+ */
+ void (*swapBuffers)(__DRInativeDisplay *dpy, void *drawablePrivate);
+
+ /**
+ * Opaque pointer to private per drawable direct rendering data.
+ * \c NULL if direct rendering is not supported on the display or
+ * screen used to create this drawable. Never dereferenced in libGL.
+ */
+ void *private;
+
+ /**
+ * Get the number of completed swap buffers for this drawable.
+ *
+ * \since Internal API version 20030317.
+ */
+ int (*getSBC)(__DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc );
+
+ /**
+ * Wait for the SBC to be greater than or equal target_sbc.
+ *
+ * \since Internal API version 20030317.
+ */
+ int (*waitForSBC)( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_sbc,
+ int64_t * msc, int64_t * sbc );
+
+ /**
+ * Wait for the MSC to equal target_msc, or, if that has already passed,
+ * the next time (MSC % divisor) is equal to remainder. If divisor is
+ * zero, the function will return as soon as MSC is greater than or equal
+ * to target_msc.
+ *
+ * \since Internal API version 20030317.
+ */
+ int (*waitForMSC)( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_msc, int64_t divisor, int64_t remainder,
+ int64_t * msc, int64_t * sbc );
+
+ /**
+ * Like \c swapBuffers, but does NOT have an implicit \c glFlush. Once
+ * rendering is complete, waits until MSC is equal to target_msc, or
+ * if that has already passed, waits until (MSC % divisor) is equal
+ * to remainder. If divisor is zero, the swap will happen as soon as
+ * MSC is greater than or equal to target_msc.
+ *
+ * \since Internal API version 20030317.
+ */
+ int64_t (*swapBuffersMSC)(__DRInativeDisplay *dpy, void *drawablePrivate,
+ int64_t target_msc,
+ int64_t divisor, int64_t remainder);
+
+ /**
+ * Enable or disable frame usage tracking.
+ *
+ * \since Internal API version 20030317.
+ */
+ int (*frameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate, GLboolean enable);
+
+ /**
+ * Retrieve frame usage information.
+ *
+ * \since Internal API version 20030317.
+ */
+ int (*queryFrameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate,
+ int64_t * sbc, int64_t * missedFrames,
+ float * lastMissedUsage, float * usage );
+
+ /**
+ * Used by drivers that implement the GLX_SGI_swap_control or
+ * GLX_MESA_swap_control extension.
+ *
+ * \since Internal API version 20030317.
+ */
+ unsigned swap_interval;
+
+ /**
+ * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
+ *
+ * \since Internal API version 20060314.
+ */
+ void (*copySubBuffer)(__DRInativeDisplay *dpy, void *drawablePrivate,
+ int x, int y, int w, int h);
+};
+
+#endif
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index cc3019fc7..604e22eaa 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -3,22 +3,47 @@ INCLUDES = \
@KDRIVE_CFLAGS@ \
-I$(srcdir)/../../../exa
-noinst_LIBRARIES = libxephyr.a libxephyr-hostx.a
+noinst_LIBRARIES = libxephyr-hostx.a libxephyr-hostxv.a libxephyr.a
bin_PROGRAMS = Xephyr
+
+libxephyr_hostx_a_SOURCES = \
+ hostx.c \
+ hostx.h
+
+libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@
+
+libxephyr_hostxv_a_SOURCES= \
+ ephyrhostvideo.c \
+ ephyrhostvideo.h
+
libxephyr_a_SOURCES = \
ephyr.c \
ephyr_draw.c \
+ ephyrvideo.c \
+ XF86dri.c \
+ ephyrdriext.c \
+ ephyrdri.c \
+ ephyrdri.h \
+ ephyrglxext.c \
+ ephyrglxext.h \
+ ephyrhostglx.c \
+ ephyrhostglx.h \
+ ephyrhostproxy.c \
+ ephyrhostproxy.h \
+ ephyrhostproxy.c \
+ ephyrproxyext.c \
+ ephyrproxyext.h \
os.c \
- hostx.h \
- ephyr.h
-
-libxephyr_hostx_a_SOURCES = \
- hostx.c \
- hostx.h
+ hostx.h \
+ ephyr.h \
+ ephyrlog.h
-libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@
+libxephyr_a_CFLAGS = \
+@LIBDRM_CFLAGS@ \
+-I$(top_srcdir) \
+@DRIPROTO_CFLAGS@
Xephyr_SOURCES = \
ephyrinit.c
@@ -26,13 +51,17 @@ Xephyr_SOURCES = \
Xephyr_LDADD = \
libxephyr.a \
libxephyr-hostx.a \
+ libxephyr-hostxv.a \
../../../exa/libexa.la \
@KDRIVE_LIBS@ \
- @XEPHYR_LIBS@
+ @XEPHYR_LIBS@ \
+ @LIBDRM_LIBS@ \
+ -lGL
Xephyr_DEPENDENCIES = \
libxephyr.a \
libxephyr-hostx.a \
+ libxephyr-hostxv.a \
@KDRIVE_LOCAL_LIBS@
relink:
diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
new file mode 100644
index 000000000..ae2ec890f
--- /dev/null
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -0,0 +1,622 @@
+/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+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, sub license, 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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:
+ * Kevin E. Martin <martin@valinux.com>
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+/*
+ * This file has been copied from the mesa source tree and a little bit
+ * modified by:
+ *
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#ifdef XEPHYR_DRI
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <GL/glx.h>
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86dristr.h>
+
+static XExtensionInfo _xf86dri_info_data;
+static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
+static char xf86dri_extension_name[] = XF86DRINAME;
+
+#define XF86DRICheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, xf86dri_extension_name, val)
+
+/*****************************************************************************
+ * *
+ * private utility routines *
+ * *
+ *****************************************************************************/
+
+static int close_display(Display *dpy, XExtCodes *extCodes);
+static /* const */ XExtensionHooks xf86dri_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info,
+ xf86dri_extension_name,
+ &xf86dri_extension_hooks,
+ 0, NULL)
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
+
+
+/*****************************************************************************
+ * *
+ * public XFree86-DRI Extension routines *
+ * *
+ *****************************************************************************/
+
+#if 0
+#include <stdio.h>
+#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
+#else
+#define TRACE(msg)
+#endif
+
+Bool XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable);
+Bool XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable);
+
+Bool XF86DRIQueryExtension (Display *dpy, int *event_basep, int *error_basep)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+
+ TRACE("QueryExtension...");
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ TRACE("QueryExtension... return True");
+ return True;
+ } else {
+ TRACE("QueryExtension... return False");
+ return False;
+ }
+}
+
+Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
+ Display* dpy;
+ int* majorVersion;
+ int* minorVersion;
+ int* patchVersion;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIQueryVersionReply rep;
+ xXF86DRIQueryVersionReq *req;
+
+ TRACE("QueryVersion...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIQueryVersion;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryVersion... return False");
+ return False;
+ }
+ *majorVersion = rep.majorVersion;
+ *minorVersion = rep.minorVersion;
+ *patchVersion = rep.patchVersion;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryVersion... return True");
+ return True;
+}
+
+Bool
+XF86DRIQueryDirectRenderingCapable (Display *dpy, int screen, Bool *isCapable)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ xXF86DRIQueryDirectRenderingCapableReq *req;
+
+ TRACE("QueryDirectRenderingCapable...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIQueryDirectRenderingCapable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryDirectRenderingCapable... return False");
+ return False;
+ }
+ *isCapable = rep.isCapable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryDirectRenderingCapable... return True");
+ return True;
+}
+
+Bool
+XF86DRIOpenConnection (Display *dpy, int screen,
+ drm_handle_t *hSAREA,
+ char **busIdString)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIOpenConnectionReply rep;
+ xXF86DRIOpenConnectionReq *req;
+
+ TRACE("OpenConnection...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIOpenConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIOpenConnection;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return False");
+ return False;
+ }
+
+ *hSAREA = rep.hSAREALow;
+ if (sizeof(drm_handle_t) == 8) {
+ int shift = 32; /* var to prevent warning on next line */
+ *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
+ }
+
+ if (rep.length) {
+ if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
+ _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return False");
+ return False;
+ }
+ _XReadPad(dpy, *busIdString, rep.busIdStringLength);
+ } else {
+ *busIdString = NULL;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return True");
+ return True;
+}
+
+Bool XF86DRIAuthConnection(dpy, screen, magic)
+ Display* dpy;
+ int screen;
+ drm_magic_t magic;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIAuthConnectionReq *req;
+ xXF86DRIAuthConnectionReply rep;
+
+ TRACE("AuthConnection...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIAuthConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIAuthConnection;
+ req->screen = screen;
+ req->magic = magic;
+ rep.authenticated = 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("AuthConnection... return False");
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("AuthConnection... return True");
+ return True;
+}
+
+Bool XF86DRICloseConnection(dpy, screen)
+ Display* dpy;
+ int screen;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRICloseConnectionReq *req;
+
+ TRACE("CloseConnection...");
+
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICloseConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICloseConnection;
+ req->screen = screen;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CloseConnection... return True");
+ return True;
+}
+
+Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
+ ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
+ Display* dpy;
+ int screen;
+ int* ddxDriverMajorVersion;
+ int* ddxDriverMinorVersion;
+ int* ddxDriverPatchVersion;
+ char** clientDriverName;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIGetClientDriverNameReply rep;
+ xXF86DRIGetClientDriverNameReq *req;
+
+ TRACE("GetClientDriverName...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetClientDriverName, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetClientDriverName;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return False");
+ return False;
+ }
+
+ *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
+ *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
+ *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
+
+ if (rep.length) {
+ if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
+ _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return False");
+ return False;
+ }
+ _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
+ } else {
+ *clientDriverName = NULL;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return True");
+ return True;
+}
+
+Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
+ hHWContext)
+ Display* dpy;
+ int screen;
+ int configID;
+ XID* context;
+ drm_context_t * hHWContext;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRICreateContextReply rep;
+ xXF86DRICreateContextReq *req;
+
+ TRACE("CreateContext...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICreateContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICreateContext;
+ req->visual = configID;
+ req->screen = screen;
+ *context = XAllocID(dpy);
+ req->context = *context;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateContext... return False");
+ return False;
+ }
+ *hHWContext = rep.hHWContext;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateContext... return True");
+ return True;
+}
+
+Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
+ Display* dpy;
+ int screen;
+ Visual* visual;
+ XID* context;
+ drm_context_t * hHWContext;
+{
+ return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
+ context, hHWContext );
+}
+
+GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
+ __DRIid context )
+{
+ Display * const dpy = (Display *) ndpy;
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIDestroyContextReq *req;
+
+ TRACE("DestroyContext...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIDestroyContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIDestroyContext;
+ req->screen = screen;
+ req->context = context;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("DestroyContext... return True");
+ return True;
+}
+
+GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
+ __DRIid drawable, drm_drawable_t * hHWDrawable )
+{
+ Display * const dpy = (Display *) ndpy;
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRICreateDrawableReply rep;
+ xXF86DRICreateDrawableReq *req;
+
+ TRACE("CreateDrawable...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICreateDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICreateDrawable;
+ req->screen = screen;
+ req->drawable = drawable;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateDrawable... return False");
+ return False;
+ }
+ *hHWDrawable = rep.hHWDrawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateDrawable... return True");
+ return True;
+}
+
+GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
+ __DRIid drawable )
+{
+ Display * const dpy = (Display *) ndpy;
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIDestroyDrawableReq *req;
+
+ TRACE("DestroyDrawable...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIDestroyDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIDestroyDrawable;
+ req->screen = screen;
+ req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("DestroyDrawable... return True");
+ return True;
+}
+
+Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
+ unsigned int* index, unsigned int* stamp,
+ int* X, int* Y, int* W, int* H,
+ int* numClipRects, drm_clip_rect_t ** pClipRects,
+ int* backX, int* backY,
+ int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIGetDrawableInfoReply rep;
+ xXF86DRIGetDrawableInfoReq *req=NULL;
+ int total_rects;
+
+ TRACE("GetDrawableInfo...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetDrawableInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetDrawableInfo;
+ req->screen = screen;
+ req->drawable = drawable;
+
+ if (!_XReply(dpy, (xReply *)&rep, 1, xFalse))
+ {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return False");
+ return False;
+ }
+ *index = rep.drawableTableIndex;
+ *stamp = rep.drawableTableStamp;
+ *X = (int)rep.drawableX;
+ *Y = (int)rep.drawableY;
+ *W = (int)rep.drawableWidth;
+ *H = (int)rep.drawableHeight;
+ *numClipRects = rep.numClipRects;
+ total_rects = *numClipRects;
+
+ *backX = rep.backX;
+ *backY = rep.backY;
+ *numBackClipRects = rep.numBackClipRects;
+ total_rects += *numBackClipRects;
+
+#if 0
+ /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
+ * backwards compatibility (Because of the >> 2 shift) but the fix
+ * enables multi-threaded apps to work.
+ */
+ if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply) +
+ total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) {
+ _XEatData(dpy, rep.length);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return False");
+ return False;
+ }
+#endif
+
+ if (*numClipRects) {
+ int len = sizeof(drm_clip_rect_t) * (*numClipRects);
+
+ *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+ if (*pClipRects)
+ _XRead(dpy, (char*)*pClipRects, len);
+ } else {
+ *pClipRects = NULL;
+ }
+
+ if (*numBackClipRects) {
+ int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
+
+ *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+ if (*pBackClipRects)
+ _XRead(dpy, (char*)*pBackClipRects, len);
+ } else {
+ *pBackClipRects = NULL;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return True");
+ return True;
+}
+
+Bool
+XF86DRIGetDeviceInfo (Display *dpy, int screen, drm_handle_t *hFrameBuffer,
+ int *fbOrigin, int *fbSize, int *fbStride,
+ int *devPrivateSize, void **pDevPrivate)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIGetDeviceInfoReply rep;
+ xXF86DRIGetDeviceInfoReq *req;
+
+ TRACE("GetDeviceInfo...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetDeviceInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetDeviceInfo;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return False");
+ return False;
+ }
+
+ *hFrameBuffer = rep.hFrameBufferLow;
+ if (sizeof(drm_handle_t) == 8) {
+ int shift = 32; /* var to prevent warning on next line */
+ *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
+ }
+
+ *fbOrigin = rep.framebufferOrigin;
+ *fbSize = rep.framebufferSize;
+ *fbStride = rep.framebufferStride;
+ *devPrivateSize = rep.devPrivateSize;
+
+ if (rep.length) {
+ if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
+ _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return False");
+ return False;
+ }
+ _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
+ } else {
+ *pDevPrivate = NULL;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return True");
+ return True;
+}
+
+Bool
+XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable)
+{
+ /* This function and the underlying X protocol are deprecated.
+ */
+ (void) dpy;
+ (void) screen;
+ (void) drawable;
+ return False;
+}
+
+Bool
+XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable)
+{
+ /* This function and the underlying X protocol are deprecated.
+ */
+ (void) dpy;
+ (void) screen;
+ (void) drawable;
+ return True;
+}
+#endif /*EPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 2e0c00491..d5a3545f5 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -23,22 +23,32 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* TODO:
- *
- * o Support multiple screens, shouldn't be hard just alot of rejigging.
- */
-
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "ephyr.h"
#include "inputstr.h"
+#include "scrnintstr.h"
+#include "ephyrlog.h"
+
+#ifdef XEPHYR_DRI
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "ephyrglxext.h"
+#include "ephyrproxyext.h"
+#endif /*XEPHYR_DRI*/
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;
@@ -48,6 +58,7 @@ typedef struct _EphyrInputPrivate {
Bool EphyrWantGrayScale = 0;
+
Bool
ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
{
@@ -83,7 +94,7 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
int width = 640, height = 480;
unsigned long redMask, greenMask, blueMask;
- if (hostx_want_screen_size(&width, &height)
+ if (hostx_want_screen_size(screen, &width, &height)
|| !screen->width || !screen->height)
{
screen->width = width;
@@ -99,13 +110,13 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
&& (screen->fb[0].depth == 24 || screen->fb[0].depth == 16
|| screen->fb[0].depth == 8))
{
- hostx_set_server_depth(screen->fb[0].depth);
+ hostx_set_server_depth(screen, screen->fb[0].depth);
}
- else
+ else
ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
}
- screen->fb[0].depth = hostx_get_server_depth();
+ screen->fb[0].depth = hostx_get_server_depth(screen);
screen->rate = 72;
if (screen->fb[0].depth <= 8)
@@ -146,7 +157,7 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
screen->fb[0].bitsPerPixel = 32;
}
- hostx_get_visual_masks (&redMask, &greenMask, &blueMask);
+ hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
screen->fb[0].redMask = (Pixel) redMask;
screen->fb[0].greenMask = (Pixel) greenMask;
@@ -194,9 +205,7 @@ ephyrWindowLinear (ScreenPtr pScreen,
EphyrPriv *priv = pScreenPriv->card->driver;
if (!pScreenPriv->enabled)
- {
- return 0;
- }
+ return 0;
*size = priv->bytes_per_line;
return priv->base + row * priv->bytes_per_line + offset;
@@ -210,8 +219,8 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
KdPointerMatrix m;
int buffer_height;
- EPHYR_DBG(" screen->width: %d, screen->height: %d",
- screen->width, screen->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);
@@ -226,8 +235,8 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
buffer_height = screen->height;
else
buffer_height = 3 * screen->height;
-
- priv->base = hostx_screen_init (screen->width, screen->height, buffer_height);
+
+ priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
screen->memory_base = (CARD8 *) (priv->base);
screen->memory_size = priv->bytes_per_line * buffer_height;
@@ -246,7 +255,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
/* Rotated/Reflected so we need to use shadow fb */
scrpriv->shadow = TRUE;
- EPHYR_DBG("allocing shadow");
+ EPHYR_LOG("allocing shadow");
KdShadowFbAlloc (screen, 0,
scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
@@ -297,14 +306,14 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
- EPHYR_DBG("slow paint");
+ 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(0,0,0,0, screen->width, screen->height);
+ hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
}
static void
@@ -314,29 +323,29 @@ ephyrInternalDamageRedisplay (ScreenPtr 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(pbox->x1, pbox->y1,
- pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- pbox++;
- }
-
+ {
+ hostx_paint_rect(screen,
+ pbox->x1, pbox->y1,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
DamageEmpty (scrpriv->pDamage);
}
}
@@ -411,7 +420,7 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
Rotation randr;
int n = 0;
- EPHYR_DBG("mark");
+ EPHYR_LOG("mark");
struct { int width, height; } sizes[] =
{
@@ -432,11 +441,11 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
{ 160, 160 },
{ 0, 0 }
};
-
+
*rotations = RR_Rotate_All|RR_Reflect_All;
-
- if (!hostx_want_preexisting_window()
- && !hostx_want_fullscreen()) /* only if no -parent switch */
+
+ if (!hostx_want_preexisting_window (screen)
+ && !hostx_want_fullscreen ()) /* only if no -parent switch */
{
while (sizes[n].width != 0 && sizes[n].height != 0)
{
@@ -564,7 +573,7 @@ ephyrRandRSetConfig (ScreenPtr pScreen,
return TRUE;
bail4:
- EPHYR_DBG("bailed");
+ EPHYR_LOG("bailed");
ephyrUnmapFramebuffer (screen);
*scrpriv = oldscr;
@@ -586,9 +595,7 @@ ephyrRandRInit (ScreenPtr pScreen)
rrScrPrivPtr pScrPriv;
if (!RRScreenInit (pScreen))
- {
- return FALSE;
- }
+ return FALSE;
pScrPriv = rrGetScrPriv(pScreen);
pScrPriv->rrGetInfo = ephyrRandRGetInfo;
@@ -606,7 +613,43 @@ ephyrCreateColormap (ColormapPtr 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 XEPHYR_DRI
+ if (!ephyrNoDRI && !hostx_has_dri ()) {
+ EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ;
+ ephyrNoDRI = TRUE ;
+ noGlxVisualInit = FALSE ;
+ }
+ if (!ephyrNoDRI) {
+ ephyrDRIExtensionInit (pScreen) ;
+ ephyrHijackGLXExtension () ;
+ ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
+ }
+#endif
+
+#ifdef GLXEXT
+ if (ephyrNoDRI) {
+ noGlxVisualInit = FALSE ;
+ }
+#endif
+
return TRUE;
}
@@ -618,12 +661,12 @@ ephyrFinishInitScreen (ScreenPtr pScreen)
*/
if (!shadowSetup (pScreen))
return FALSE;
-
+
#ifdef RANDR
if (!ephyrRandRInit (pScreen))
return FALSE;
#endif
-
+
return TRUE;
}
@@ -634,7 +677,8 @@ ephyrCreateResources (ScreenPtr pScreen)
KdScreenInfo *screen = pScreenPriv->screen;
EphyrScrPriv *scrpriv = screen->driver;
- EPHYR_DBG("mark");
+ EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
+ pScreen, pScreen->myNum, scrpriv->shadow);
if (scrpriv->shadow)
return KdShadowSet (pScreen,
@@ -743,6 +787,56 @@ ephyrUpdateModifierState(unsigned int state)
}
}
+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 (ScreenPtr pScreen, int x, int y)
+{
+ ephyrBlockSigio ();
+ ephyrCurScreen = pScreen->myNum;
+ miPointerWarpCursor (pScreen, x, y);
+ ephyrUnblockSigio ();
+}
+
+miPointerScreenFuncRec ephyrPointerScreenFuncs =
+{
+ ephyrCursorOffScreen,
+ ephyrCrossScreen,
+ ephyrWarpCursor
+};
+
+
void
ephyrPoll(void)
{
@@ -751,21 +845,39 @@ ephyrPoll(void)
while (hostx_get_event(&ev))
{
switch (ev.type)
- {
- case EPHYR_EV_MOUSE_MOTION:
+ {
+ case EPHYR_EV_MOUSE_MOTION:
if (!ephyrMouse ||
- !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
continue;
- KdEnqueuePointerEvent(ephyrMouse, mouseState,
- ev.data.mouse_motion.x,
- ev.data.mouse_motion.y,
- 0);
- break;
-
- case EPHYR_EV_MOUSE_PRESS:
+ }
+ {
+ if (ephyrCurScreen != ev.data.mouse_motion.screen)
+ {
+ EPHYR_LOG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
+ ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen],
+ ev.data.mouse_motion.x,
+ ev.data.mouse_motion.y );
+ }
+ else
+ {
+ EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState,
+ ev.data.mouse_motion.x,
+ ev.data.mouse_motion.y,
+ 0);
+ }
+ }
+ break;
+
+ case EPHYR_EV_MOUSE_PRESS:
if (!ephyrMouse ||
- !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+ !((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);
@@ -777,6 +889,7 @@ ephyrPoll(void)
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;
@@ -792,7 +905,6 @@ ephyrPoll(void)
if (!ephyrKbd ||
!((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
continue;
- ephyrUpdateModifierState(ev.key_state);
KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
break;
@@ -814,7 +926,7 @@ ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
/* XXX Not sure if this is right */
- EPHYR_DBG("mark");
+ EPHYR_LOG("mark");
while (n--)
{
@@ -953,6 +1065,7 @@ EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
{
}
+
KdKeyboardDriver EphyrKeyboardDriver = {
"ephyr",
EphyrKeyboardInit,
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index f49d920d1..8ed7e23dd 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -71,6 +71,8 @@ extern KdCardFuncs ephyrFuncs;
extern KdKeyboardInfo *ephyrKbd;
extern KdPointerInfo *ephyrMouse;
+extern miPointerScreenFuncRec ephyrPointerScreenFuncs;
+
Bool
ephyrInitialize (KdCardInfo *card, EphyrPriv *priv);
@@ -192,4 +194,8 @@ ephyrDrawDisable(ScreenPtr pScreen);
void
ephyrDrawFini(ScreenPtr pScreen);
+/*ephyvideo.c*/
+
+Bool ephyrInitVideo(ScreenPtr pScreen) ;
+
#endif
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
new file mode 100644
index 000000000..53a96ba11
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -0,0 +1,291 @@
+/*
+ * 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
+
+#ifdef XEPHYR_DRI
+
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+/*#define _XF86DRI_SERVER_*/
+#include <GL/glx.h>
+#include <X11/dri/xf86dri.h>
+#include "hostx.h"
+#include "ephyrdri.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif /*TRUE*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif /*FALSE*/
+
+Bool
+ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
+{
+ Display *dpy=hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_is_capable, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIQueryDirectRenderingCapable (dpy, DefaultScreen (dpy),
+ a_is_capable) ;
+ EPHYR_LOG ("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok) ;
+
+ return is_ok ;
+}
+
+Bool
+ephyrDRIOpenConnection (int a_screen,
+ drm_handle_t *a_sarea,
+ char **a_bus_id_string)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_bus_id_string, FALSE) ;
+ EPHYR_LOG ("enter. screen:%d\n", a_screen) ;
+ is_ok = XF86DRIOpenConnection (dpy, DefaultScreen (dpy),
+ a_sarea,
+ a_bus_id_string) ;
+ if (*a_bus_id_string) {
+ EPHYR_LOG ("leave. bus_id_string:%s, is_ok:%d\n",
+ *a_bus_id_string, is_ok) ;
+ } else {
+ EPHYR_LOG ("leave. bus_id_string:null, is_ok:%d\n",
+ is_ok) ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIAuthConnection (dpy, DefaultScreen (dpy), a_magic) ;
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRICloseConnection (int a_screen)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRICloseConnection (dpy, DefaultScreen (dpy)) ;
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIGetClientDriverName (int a_screen,
+ int *a_ddx_driver_major_version,
+ int *a_ddx_driver_minor_version,
+ int *a_ddx_driver_patch_version,
+ char ** a_client_driver_name)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_ddx_driver_major_version
+ && a_ddx_driver_minor_version
+ && a_ddx_driver_patch_version
+ && a_client_driver_name,
+ FALSE);
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIGetClientDriverName (dpy, DefaultScreen (dpy),
+ a_ddx_driver_major_version,
+ a_ddx_driver_minor_version,
+ a_ddx_driver_patch_version,
+ a_client_driver_name) ;
+ EPHYR_LOG ("major:%d, minor:%d, patch:%d, name:%s\n",
+ *a_ddx_driver_major_version,
+ *a_ddx_driver_minor_version,
+ *a_ddx_driver_patch_version,
+ *a_client_driver_name) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRICreateContext (int a_screen,
+ int a_visual_id,
+ unsigned long int *a_returned_ctxt_id,
+ drm_context_t *a_hw_ctxt)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+ Visual v;
+
+ EPHYR_LOG ("enter. screen:%d, visual:%d\n", a_screen, a_visual_id) ;
+ memset (&v, 0, sizeof (v)) ;
+ v.visualid = a_visual_id ;
+ is_ok = XF86DRICreateContext (dpy,
+ DefaultScreen (dpy),
+ &v,
+ a_returned_ctxt_id,
+ a_hw_ctxt) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIDestroyContext (int a_screen,
+ int a_context_id)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIDestroyContext (dpy, DefaultScreen (dpy), a_context_id) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRICreateDrawable (int a_screen,
+ int a_drawable,
+ drm_drawable_t *a_hw_drawable)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRICreateDrawable (dpy, DefaultScreen (dpy),
+ a_drawable, a_hw_drawable) ;
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
+{
+ EPHYR_LOG ("enter\n") ;
+ EPHYR_LOG_ERROR ("not implemented yet\n") ;
+ EPHYR_LOG ("leave\n") ;
+ return FALSE ;
+}
+
+Bool
+ephyrDRIGetDrawableInfo (int a_screen,
+ int a_drawable,
+ unsigned int *a_index,
+ unsigned int *a_stamp,
+ int *a_x,
+ int *a_y,
+ int *a_w,
+ int *a_h,
+ int *a_num_clip_rects,
+ drm_clip_rect_t **a_clip_rects,
+ int *a_back_x,
+ int *a_back_y,
+ int *a_num_back_clip_rects,
+ drm_clip_rect_t **a_back_clip_rects)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+ EphyrHostWindowAttributes attrs ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_x && a_y && a_w && a_h
+ && a_num_clip_rects,
+ FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ memset (&attrs, 0, sizeof (attrs)) ;
+ if (!hostx_get_window_attributes (a_drawable, &attrs)) {
+ EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
+ goto out;
+ }
+ if (!XF86DRIGetDrawableInfo (dpy, DefaultScreen (dpy), a_drawable,
+ a_index, a_stamp,
+ a_x, a_y,
+ a_w, a_h,
+ a_num_clip_rects, a_clip_rects,
+ a_back_x, a_back_y,
+ a_num_back_clip_rects,
+ a_back_clip_rects)) {
+ EPHYR_LOG_ERROR ("XF86DRIGetDrawableInfo ()\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h) ;
+ if (*a_num_clip_rects) {
+ free (*a_back_clip_rects) ;
+ *a_back_clip_rects = calloc (*a_num_clip_rects,
+ sizeof (drm_clip_rect_t)) ;
+ memmove (*a_back_clip_rects,
+ *a_clip_rects,
+ *a_num_clip_rects * sizeof (drm_clip_rect_t)) ;
+ *a_num_back_clip_rects = *a_num_clip_rects;
+ }
+ EPHYR_LOG ("num back clip rects:%d, num clip rects:%d\n",
+ *a_num_clip_rects, *a_num_back_clip_rects) ;
+ *a_back_x = *a_x ;
+ *a_back_y = *a_y ;
+ *a_w = attrs.width;
+ *a_h = attrs.height;
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n",
+ *a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIGetDeviceInfo (int a_screen,
+ drm_handle_t *a_frame_buffer,
+ int *a_fb_origin,
+ int *a_fb_size,
+ int *a_fb_stride,
+ int *a_dev_private_size,
+ void **a_dev_private)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIGetDeviceInfo (dpy, DefaultScreen (dpy), a_frame_buffer,
+ a_fb_origin, a_fb_size, a_fb_stride,
+ a_dev_private_size, a_dev_private) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+#endif /*EPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/ephyrdri.h b/hw/kdrive/ephyr/ephyrdri.h
new file mode 100644
index 000000000..af8bb11fd
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdri.h
@@ -0,0 +1,75 @@
+/*
+ * 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>
+ */
+
+#ifndef __EPHYRDRI_H__
+#define __EPHYRDRI_H__
+
+#include <xf86drm.h>
+
+Bool ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable) ;
+Bool ephyrDRIOpenConnection (int screen, drm_handle_t *a_sarea, char **a_bus_id_string) ;
+Bool ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic) ;
+Bool ephyrDRICloseConnection (int a_screen) ;
+Bool ephyrDRIGetClientDriverName (int a_screen,
+ int *a_ddx_driver_major_version,
+ int *a_ddx_driver_minor_version,
+ int *a_ddx_driver_patch_version,
+ char ** a_client_driver_name) ;
+Bool ephyrDRICreateContext (int a_screen,
+ int a_visual_id,
+ unsigned long int *a_returned_ctx_id,
+ drm_context_t *a_hw_ctx) ;
+Bool ephyrDRIDestroyContext (int a_screen,
+ int a_context_id) ;
+Bool ephyrDRICreateDrawable (int a_screen,
+ int a_drawable,
+ drm_drawable_t *a_hw_drawable) ;
+Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
+Bool ephyrDRIGetDrawableInfo (int a_screen,
+ int /*Drawable*/a_drawable,
+ unsigned int *a_index,
+ unsigned int *a_stamp,
+ int *a_x,
+ int *a_y,
+ int *a_w,
+ int *a_h,
+ int *a_num_clip_rects,
+ drm_clip_rect_t **a_clip_rects,
+ int *a_back_x,
+ int *a_back_y,
+ int *num_back_clip_rects,
+ drm_clip_rect_t **a_back_clip_rects) ;
+Bool ephyrDRIGetDeviceInfo (int a_screen,
+ drm_handle_t *a_frame_buffer,
+ int *a_fb_origin,
+ int *a_fb_size,
+ int *a_fb_stride,
+ int *a_dev_private_size,
+ void **a_dev_private) ;
+#endif /*__EPHYRDRI_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
new file mode 100644
index 000000000..e3d0cfbb4
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -0,0 +1,1448 @@
+/*
+ * 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
+
+#ifdef XEPHYR_DRI
+
+#include <string.h>
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86dristr.h>
+#include "misc.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"
+
+typedef struct {
+ WindowPtr local ;
+ int remote ;
+} EphyrWindowPair;
+
+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 void XF86DRIResetProc(ExtensionEntry* extEntry);
+
+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 ephyrDRIGeneration=-1 ;
+static int ephyrDRIWindowIndex=-1 ;
+static int ephyrDRIScreenIndex=-1 ;
+
+#define GET_EPHYR_DRI_WINDOW_PRIV(win) \
+ ((EphyrDRIWindowPrivPtr)((win)->devPrivates[ephyrDRIWindowIndex].ptr))
+#define GET_EPHYR_DRI_SCREEN_PRIV(screen) \
+ ((EphyrDRIScreenPrivPtr)((screen)->devPrivates[ephyrDRIScreenIndex].ptr))
+
+
+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);
+#endif
+
+ if ((extEntry = AddExtension(XF86DRINAME,
+ XF86DRINumberEvents,
+ XF86DRINumberErrors,
+ ProcXF86DRIDispatch,
+ SProcXF86DRIDispatch,
+ XF86DRIResetProc,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ } else {
+ EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
+ goto out ;
+ }
+ if (ephyrDRIGeneration != serverGeneration) {
+ ephyrDRIScreenIndex = AllocateScreenPrivateIndex () ;
+ if (ephyrDRIScreenIndex < 0) {
+ EPHYR_LOG_ERROR ("failed to allocate screen priv index\n") ;
+ goto out ;
+ }
+ }
+ screen_priv = xcalloc (1, sizeof (EphyrDRIScreenPrivRec)) ;
+ if (!screen_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
+ goto out ;
+ }
+ a_screen->devPrivates[ephyrDRIScreenIndex].ptr = screen_priv;
+
+ if (!ephyrDRIScreenInit (a_screen)) {
+ EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
+ goto out ;
+ }
+ EphyrMirrorHostVisuals (a_screen) ;
+ if (ephyrDRIGeneration != serverGeneration) {
+ ephyrDRIGeneration = serverGeneration ;
+ }
+ 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) ;
+
+ if (ephyrDRIGeneration != serverGeneration) {
+ ephyrDRIWindowIndex = AllocateWindowPrivateIndex () ;
+ if (ephyrDRIWindowIndex < 0) {
+ EPHYR_LOG_ERROR ("failed to allocate window priv index\n") ;
+ goto out ;
+ }
+ }
+ if (!AllocateWindowPrivate (a_screen, ephyrDRIWindowIndex, 0)) {
+ EPHYR_LOG_ERROR ("failed to allocate window privates\n") ;
+ goto out ;
+ }
+ 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 ;
+out:
+ 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:%#x\n",
+ (unsigned int)a_win) ;
+
+ screen->CreateWindow = screen_priv->CreateWindow ;
+ is_ok = (*screen->CreateWindow) (a_win) ;
+ screen->CreateWindow = ephyrDRICreateWindow ;
+
+ if (is_ok) {
+ a_win->devPrivates[ephyrDRIWindowIndex].ptr = 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) ;
+ a_win->devPrivates[ephyrDRIWindowIndex].ptr = 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: %#x\n", (unsigned int)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: %#x\n", (unsigned int)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: %#x\n", (unsigned int)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:
+ if (rects) {
+ 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:
+ if (new_visuals) {
+ 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;
+}
+
+
+/*ARGSUSED*/
+static void
+XF86DRIResetProc (
+ ExtensionEntry* extEntry
+)
+{
+}
+
+static int
+ProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ xXF86DRIQueryVersionReply rep;
+ register int n;
+
+ EPHYR_LOG ("enter\n") ;
+
+ REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = XF86DRI_MAJOR_VERSION;
+ rep.minorVersion = XF86DRI_MINOR_VERSION;
+ rep.patchVersion = 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;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+ 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;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIOpenConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+ 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 = (SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+ ((rep.busIdStringLength + 3) & ~3)) >> 2;
+
+ 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;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+ 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)
+{
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRICloseConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ 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;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIGetClientDriverNameReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+ 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 = (SIZEOF(xXF86DRIGetClientDriverNameReply) -
+ SIZEOF(xGenericReply) +
+ ((rep.clientDriverNameLength + 3) & ~3)) >> 2;
+
+ 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;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRICreateContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+ 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)
+{
+ EPHYR_LOG ("enter\n") ;
+
+ REQUEST(xXF86DRIDestroyContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ 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):(%#x, %d)\n", (unsigned int)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 (%#x, %d)\n",
+ (unsigned int)(*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 '%#x'\n", (unsigned int)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;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRICreateDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+ 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 %#x\n", (unsigned int)drawable) ;
+ window = (WindowPtr)drawable;
+ if (findWindowPairFromLocal (window, &pair) && pair) {
+ remote_win = pair->remote ;
+ EPHYR_LOG ("found window '%#x' paire with remote '%d'\n",
+ (unsigned int)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 ;
+ }
+ window->devPrivates[ephyrDRIWindowIndex].ptr = win_priv ;
+ EPHYR_LOG ("paired window '%#x' with remote '%d'\n",
+ (unsigned int)window, remote_win) ;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIDestroyDrawable (register ClientPtr client)
+{
+ REQUEST(xXF86DRIDestroyDrawableReq);
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+ int rc=0;
+
+ 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;
+
+ EPHYR_LOG ("enter\n") ;
+ memset (&rep, 0, sizeof (rep)) ;
+ REQUEST(xXF86DRIGetDrawableInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+ 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 = ((rep.length + 3) & ~3) >> 2;
+
+ 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);
+ }
+ if (clipRects) {
+ 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;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+ 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 = (SIZEOF(xXF86DRIGetDeviceInfoReply) -
+ SIZEOF(xGenericReply) +
+ ((rep.devPrivateSize + 3) & ~3)) >> 2;
+ }
+
+ 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;
+ }
+ }
+}
+
+#endif /*XEPHYR_DRI*/
diff --git a/hw/kdrive/ephyr/ephyrdriext.h b/hw/kdrive/ephyr/ephyrdriext.h
new file mode 100644
index 000000000..66af833b9
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdriext.h
@@ -0,0 +1,32 @@
+/*
+ * 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>
+ */
+#ifndef __EPHYRDRIEXT_H__
+#define __EPHYRDRIEXT_H__
+Bool ephyrDRIExtensionInit (ScreenPtr a_screen) ;
+#endif /*__EPHYRDRIEXT_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
new file mode 100644
index 000000000..381c9d7ed
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -0,0 +1,722 @@
+/*
+ * 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 "GL/glx/glxserver.h"
+#include "GL/glx/indirect_table.h"
+#include "GL/glx/indirect_util.h"
+#include "GL/glx/unpack.h"
+#include "hostx.h"
+
+
+#ifdef XEPHYR_DRI
+
+#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") ;
+ if (props_buf) {
+ 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") ;
+ if (props_buf) {
+ 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 ;
+ 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 ;
+
+ WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
+ WriteToClient(client, (int)length, server_string);
+
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ if (server_string) {
+ xfree (server_string) ;
+ server_string = 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) ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/ephyrglxext.h b/hw/kdrive/ephyr/ephyrglxext.h
new file mode 100644
index 000000000..22ea605d7
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrglxext.h
@@ -0,0 +1,35 @@
+/*
+ * 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>
+ */
+#ifndef __EPHYR_GLXEXT_H__
+#define __EPHYR_GLXEXT_H__
+
+#include <X11/Xdefs.h>
+Bool ephyrHijackGLXExtension (void) ;
+
+#endif /*__EPHYR_GLXEXT_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
new file mode 100644
index 000000000..5d9a482e8
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -0,0 +1,687 @@
+/*
+ * 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.
+ *
+ * a lots of the content of this file has been adapted from the mesa source
+ * code.
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <X11/Xlibint.h>
+#include <GL/glx.h>
+#include <GL/internal/glcore.h>
+#include <GL/glxproto.h>
+#include <GL/glxint.h>
+#include "ephyrhostglx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "hostx.h"
+
+#ifdef XEPHYR_DRI
+enum VisualConfRequestType {
+ EPHYR_GET_FB_CONFIG,
+ EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
+ EPHYR_GET_VISUAL_CONFIGS
+
+};
+
+static Bool ephyrHostGLXGetVisualConfigsInternal
+ (enum VisualConfRequestType a_type,
+ int32_t a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf);
+Bool
+ephyrHostGLXGetMajorOpcode (int *a_opcode)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy=hostx_get_display () ;
+ static int opcode ;
+ int first_event_return=0, first_error_return=0;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+ if (!opcode) {
+ if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode,
+ &first_event_return, &first_error_return)) {
+ EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ;
+ goto out ;
+ }
+ }
+ *a_opcode = opcode ;
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("release\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+ int major_opcode=0;
+ xGLXQueryVersionReq *req=NULL;
+ xGLXQueryVersionReply reply;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
+
+ /* Send the glXQueryVersion request */
+ memset (&reply, 0, sizeof (reply)) ;
+ LockDisplay (dpy);
+ GetReq (GLXQueryVersion, req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXQueryVersion;
+ req->majorVersion = 2;
+ req->minorVersion = 1;
+ _XReply(dpy, (xReply*) &reply, 0, False);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ *a_major = reply.majorVersion ;
+ *a_minor = reply.minorVersion ;
+
+ EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ;
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+/**
+ * GLX protocol structure for the ficticious "GXLGenericGetString" request.
+ *
+ * This is a non-existant protocol packet. It just so happens that all of
+ * the real protocol packets used to request a string from the server have
+ * an identical binary layout. The only difference between them is the
+ * meaning of the \c for_whom field and the value of the \c glxCode.
+ * (this has been copied from the mesa source code)
+ */
+typedef struct GLXGenericGetString {
+ CARD8 reqType;
+ CARD8 glxCode;
+ CARD16 length B16;
+ CARD32 for_whom B32;
+ CARD32 name B32;
+} xGLXGenericGetStringReq;
+
+/* These defines are only needed to make the GetReq macro happy.
+ */
+#define sz_xGLXGenericGetStringReq 12
+#define X_GLXGenericGetString 0
+
+Bool
+ephyrHostGLXGetStringFromServer (int a_screen_number,
+ int a_string_name,
+ enum EphyrHostGLXGetStringOps a_op,
+ char **a_string)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy = hostx_get_display () ;
+ xGLXGenericGetStringReq *req=NULL;
+ xGLXSingleReply reply;
+ int length=0, numbytes=0, major_opcode=0, get_string_op=0;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ switch (a_op) {
+ case EPHYR_HOST_GLX_QueryServerString:
+ get_string_op = X_GLXQueryServerString;
+ break ;
+ case EPHYR_HOST_GLX_GetString:
+ get_string_op = X_GLsop_GetString;
+ EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n",
+ a_string_name, a_screen_number) ;
+ break ;
+ default:
+ EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ;
+ goto out ;
+ }
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
+
+ LockDisplay (dpy);
+
+ /* All of the GLX protocol requests for getting a string from the server
+ * look the same. The exact meaning of the a_for_whom field is usually
+ * either the screen number (for glXQueryServerString) or the context tag
+ * (for GLXSingle).
+ */
+ GetReq (GLXGenericGetString, req);
+ req->reqType = major_opcode;
+ req->glxCode = get_string_op;
+ req->for_whom = DefaultScreen (dpy);
+ req->name = a_string_name;
+
+ _XReply (dpy, (xReply *)&reply, 0, False);
+
+ length = reply.length * 4;
+ numbytes = reply.size;
+ EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ;
+
+ *a_string = (char *) Xmalloc (numbytes +1);
+ if (!a_string) {
+ EPHYR_LOG_ERROR ("allocation failed\n") ;
+ goto out;
+ }
+
+ memset (*a_string, 0, numbytes+1) ;
+ if (_XRead (dpy, *a_string, numbytes)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ EPHYR_LOG_ERROR ("read failed\n") ;
+ goto out ;
+ }
+ length -= numbytes;
+ _XEatData (dpy, length) ;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n",
+ a_string_name, *a_string, numbytes) ;
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
+ int32_t a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+ xGLXGetVisualConfigsReq *req;
+ xGLXGetFBConfigsReq *fb_req;
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXGetFBConfigsSGIXReq *sgi_req;
+ xGLXGetVisualConfigsReply reply;
+ char *server_glx_version=NULL,
+ *server_glx_extensions=NULL ;
+ int j=0,
+ screens=0,
+ major_opcode=0,
+ num_props=0,
+ num_visuals=0,
+ props_buf_size=0,
+ props_per_visual_size=0;
+ int32_t *props_buf=NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ screens = ScreenCount (dpy);
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get opcode\n") ;
+ goto out ;
+ }
+
+ LockDisplay(dpy);
+ switch (a_type) {
+ case EPHYR_GET_FB_CONFIG:
+ GetReq(GLXGetFBConfigs,fb_req);
+ fb_req->reqType = major_opcode;
+ fb_req->glxCode = X_GLXGetFBConfigs;
+ fb_req->screen = DefaultScreen (dpy);
+ break;
+
+ case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXGetFBConfigsSGIXReq
+ -
+ sz_xGLXVendorPrivateWithReplyReq,
+ vpreq);
+ sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+ sgi_req->reqType = major_opcode;
+ sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+ sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+ sgi_req->screen = DefaultScreen (dpy);
+ break;
+
+ case EPHYR_GET_VISUAL_CONFIGS:
+ GetReq(GLXGetVisualConfigs,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXGetVisualConfigs;
+ req->screen = DefaultScreen (dpy);
+ break;
+ }
+
+ if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
+ EPHYR_LOG_ERROR ("unknown error\n") ;
+ UnlockDisplay(dpy);
+ goto out ;
+ }
+ if (!reply.numVisuals) {
+ EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ;
+ UnlockDisplay(dpy);
+ goto out ;
+ }
+ num_visuals = reply.numVisuals ;
+
+ /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
+ * FIXME: FBconfigs?
+ */
+ /* Check number of properties */
+ num_props = reply.numProps;
+ if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
+ (num_props > __GLX_MAX_CONFIG_PROPS)) {
+ /* Huh? Not in protocol defined limits. Punt */
+ EPHYR_LOG_ERROR ("got a bad reply to request\n") ;
+ UnlockDisplay(dpy);
+ goto out ;
+ }
+
+ if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
+ num_props *= 2;
+ }
+ props_per_visual_size = num_props * __GLX_SIZE_INT32;
+ props_buf_size = props_per_visual_size * reply.numVisuals;
+ props_buf = malloc (props_buf_size) ;
+ for (j = 0; j < reply.numVisuals; j++) {
+ if (_XRead (dpy,
+ &((char*)props_buf)[j*props_per_visual_size],
+ props_per_visual_size) != Success) {
+ EPHYR_LOG_ERROR ("read failed\n") ;
+ }
+ }
+ UnlockDisplay(dpy);
+
+ *a_num_visuals = num_visuals ;
+ *a_num_props = reply.numProps ;
+ *a_props_buf_size = props_buf_size ;
+ *a_props_buf = props_buf ;
+ is_ok = TRUE ;
+
+out:
+ if (server_glx_version) {
+ XFree (server_glx_version) ;
+ server_glx_version = NULL ;
+ }
+ if (server_glx_extensions) {
+ XFree (server_glx_extensions) ;
+ server_glx_extensions = NULL ;
+ }
+ SyncHandle () ;
+ return is_ok;
+}
+
+Bool
+ephyrHostGLXGetVisualConfigs (int32_t a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf)
+{
+ Bool is_ok = FALSE;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS,
+ a_screen,
+ a_num_visuals,
+ a_num_props,
+ a_props_buf_size,
+ a_props_buf) ;
+
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok;
+}
+
+Bool
+ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf)
+{
+ Bool is_ok=FALSE ;
+ EPHYR_LOG ("enter\n") ;
+ is_ok = ephyrHostGLXGetVisualConfigsInternal
+ (EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
+ a_screen,
+ a_num_visuals,
+ a_num_props,
+ a_props_buf_size,
+ a_props_buf) ;
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
+ const char* a_extension_list)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+ xGLXClientInfoReq *req;
+ int size;
+ int32_t major_opcode=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+
+ LockDisplay (dpy);
+
+ GetReq (GLXClientInfo,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXClientInfo;
+ req->major = a_major;
+ req->minor = a_minor;
+
+ size = strlen (a_extension_list) + 1;
+ req->length += (size + 3) >> 2;
+ req->numbytes = size;
+ Data (dpy, a_extension_list, size);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ is_ok=TRUE ;
+
+out:
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXCreateContext (int a_screen,
+ int a_visual_id,
+ int a_context_id,
+ int a_share_list_ctxt_id,
+ Bool a_direct)
+{
+ Bool is_ok = FALSE;
+ Display *dpy = hostx_get_display ();
+ int major_opcode=0, remote_context_id=0;
+ xGLXCreateContextReq *req;
+
+ EPHYR_LOG ("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n",
+ a_screen, a_visual_id, a_context_id, a_direct) ;
+
+ if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) {
+ EPHYR_LOG_ERROR ("failed to peer the context id %d host X",
+ remote_context_id) ;
+ goto out ;
+ }
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+
+ LockDisplay (dpy) ;
+
+ /* Send the glXCreateContext request */
+ GetReq(GLXCreateContext,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXCreateContext;
+ req->context = remote_context_id;
+ req->visual = a_visual_id;
+ req->screen = DefaultScreen (dpy);
+ req->shareList = a_share_list_ctxt_id;
+ req->isDirect = a_direct;
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostDestroyContext (int a_ctxt_id)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display ();
+ int major_opcode=0, remote_ctxt_id=0 ;
+ xGLXDestroyContextReq *req=NULL;
+
+ EPHYR_LOG ("enter:%d\n", a_ctxt_id) ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) {
+ EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ;
+
+ LockDisplay (dpy);
+ GetReq (GLXDestroyContext,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXDestroyContext;
+ req->context = remote_ctxt_id;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXMakeCurrent (int a_drawable,
+ int a_glx_ctxt_id,
+ int a_old_ctxt_tag,
+ int *a_ctxt_tag)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy = hostx_get_display () ;
+ int32_t major_opcode=0 ;
+ int remote_glx_ctxt_id=0 ;
+ xGLXMakeCurrentReq *req;
+ xGLXMakeCurrentReply reply;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_ctxt_tag, FALSE) ;
+
+ EPHYR_LOG ("enter. drawable:%d, context:%d, oldtag:%d\n",
+ a_drawable, a_glx_ctxt_id, a_old_ctxt_tag) ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) {
+ EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+ goto out ;
+ }
+
+ LockDisplay (dpy);
+
+ GetReq (GLXMakeCurrent,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXMakeCurrent;
+ req->drawable = a_drawable;
+ req->context = remote_glx_ctxt_id;
+ req->oldContextTag = a_old_ctxt_tag;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!_XReply (dpy, (xReply*)&reply, 0, False)) {
+ EPHYR_LOG_ERROR ("failed to get reply from host\n") ;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ goto out ;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *a_ctxt_tag = reply.contextTag ;
+ EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+#define X_GLXSingle 0
+
+#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \
+ *((INT8 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \
+ *((INT16 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \
+ *((INT32 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \
+ *((FLOAT32 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_READ_XREPLY() \
+ (void) _XReply(dpy, (xReply*) &reply, 0, False)
+
+#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \
+ a = (cast) reply.retval
+
+#define EPHYR_GLX_SINGLE_GET_SIZE(a) \
+ a = (GLint) reply.size
+
+#define EPHYR_GLX_SINGLE_GET_CHAR(p) \
+ *p = *(GLbyte *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_SHORT(p) \
+ *p = *(GLshort *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_LONG(p) \
+ *p = *(GLint *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \
+ *p = *(GLfloat *)&reply.pad3;
+
+Bool
+ephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val)
+{
+ Bool is_ok=FALSE;
+ Display *dpy = hostx_get_display () ;
+ int major_opcode=0, size=0;
+ xGLXSingleReq *req=NULL;
+ xGLXSingleReply reply;
+ unsigned char* pc=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ LockDisplay (dpy) ;
+ GetReqExtra (GLXSingle, 4, req) ;
+ req->reqType = major_opcode ;
+ req->glxCode = X_GLsop_GetIntegerv ;
+ req->contextTag = a_current_context_tag;
+ pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ;
+ EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ;
+ EPHYR_GLX_SINGLE_READ_XREPLY () ;
+ EPHYR_GLX_SINGLE_GET_SIZE (size) ;
+ if (!size) {
+ UnlockDisplay (dpy) ;
+ SyncHandle () ;
+ EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ;
+ goto out ;
+ }
+ EPHYR_GLX_SINGLE_GET_LONG (a_val) ;
+ UnlockDisplay (dpy) ;
+ SyncHandle () ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostIsContextDirect (int a_ctxt_id,
+ int *a_is_direct)
+{
+ Bool is_ok=FALSE;
+ Display *dpy = hostx_get_display () ;
+ xGLXIsDirectReq *req=NULL;
+ xGLXIsDirectReply reply;
+ int major_opcode=0, remote_glx_ctxt_id=0;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
+ EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+ goto out ;
+ }
+ memset (&reply, 0, sizeof (reply)) ;
+
+ /* Send the glXIsDirect request */
+ LockDisplay (dpy);
+ GetReq (GLXIsDirect,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXIsDirect;
+ req->context = remote_glx_ctxt_id;
+ if (!_XReply (dpy, (xReply*) &reply, 0, False)) {
+ EPHYR_LOG_ERROR ("fail in reading reply from host\n") ;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ goto out ;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *a_is_direct = reply.isDirect ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h
new file mode 100644
index 000000000..6db362f30
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostglx.h
@@ -0,0 +1,76 @@
+/*
+ * 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>
+ */
+#ifndef __EPHYRHOSTGLX_H__
+#define __EPHYRHOSTGLX_H__
+
+enum EphyrHostGLXGetStringOps {
+ EPHYR_HOST_GLX_UNDEF,
+ EPHYR_HOST_GLX_QueryServerString,
+ EPHYR_HOST_GLX_GetString,
+};
+
+Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
+Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
+ int a_string_name,
+ enum EphyrHostGLXGetStringOps a_op,
+ char **a_string) ;
+Bool ephyrHostGLXGetVisualConfigs (int a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf) ;
+Bool
+ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf);
+Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
+Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
+ const char* a_extension_list) ;
+Bool ephyrHostGLXCreateContext (int a_screen,
+ int a_visual_id,
+ int a_context_id,
+ int a_shared_list_ctx_id,
+ Bool a_direct) ;
+
+Bool ephyrHostDestroyContext (int a_ctxt_id) ;
+
+Bool ephyrHostGLXMakeCurrent (int a_drawable, int a_glx_ctxt_id,
+ int a_olg_ctxt_tag, int *a_ctxt_tag) ;
+
+Bool ephyrHostGetIntegerValue (int a_current_context_tag,
+ int a_int,
+ int *a_val) ;
+
+Bool ephyrHostIsContextDirect (int a_ctxt_id,
+ int *a_is_direct) ;
+
+
+#endif /*__EPHYRHOSTGLX_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrhostproxy.c b/hw/kdrive/ephyr/ephyrhostproxy.c
new file mode 100644
index 000000000..ce3f01852
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostproxy.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <X11/Xlibint.h>
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "ephyrhostproxy.h"
+#include "hostx.h"
+
+/* byte swap a short */
+#define swaps(x, n) { \
+ n = ((char *) (x))[0];\
+ ((char *) (x))[0] = ((char *) (x))[1];\
+ ((char *) (x))[1] = n; }
+
+#define GetXReq(req) \
+ WORD64ALIGN ;\
+ if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xReq *)(dpy->last_req = dpy->bufptr);\
+ dpy->bufptr += SIZEOF(xReq);\
+ dpy->request++
+
+
+Bool
+ephyrHostProxyDoForward (pointer a_request_buffer,
+ struct XReply *a_reply,
+ Bool a_do_swap)
+{
+ Bool is_ok = FALSE ;
+ int n=0 ;
+ Display *dpy=hostx_get_display () ;
+ xReq *in_req = (xReq*) a_request_buffer ;
+ xReq *forward_req=NULL ;
+ struct XReply reply ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (in_req && dpy, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_do_swap) {
+ swaps (&in_req->length, n) ;
+ }
+ EPHYR_LOG ("Req {type:%d, data:%d, length:%d}\n",
+ in_req->reqType, in_req->data, in_req->length) ;
+ GetXReq (forward_req) ;
+ memmove (forward_req, in_req, 4) ;
+
+ if (!_XReply (dpy, (xReply*) &reply, 0, FALSE)) {
+ EPHYR_LOG_ERROR ("failed to get reply\n") ;
+ goto out;
+ }
+ EPHYR_LOG ("XReply{type:%d, foo:%d, seqnum:%d, length:%d}\n",
+ reply.type, reply.foo, reply.sequence_number, reply.length) ;
+
+ if (a_reply) {
+ memmove (a_reply, &reply, sizeof (reply)) ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrhostproxy.h b/hw/kdrive/ephyr/ephyrhostproxy.h
new file mode 100644
index 000000000..720c986ff
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostproxy.h
@@ -0,0 +1,51 @@
+/*
+ * 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>
+ */
+
+#ifndef __EPHYRHOSTPROXY_H__
+#define __EPHYRHOSTPROXY_H__
+
+struct XReply {
+ int8_t type ;/*X_Reply*/
+ int8_t foo;
+ int16_t sequence_number ;
+ int32_t length ;
+ /*following is some data up to 32 bytes lenght*/
+ int32_t pad0 ;
+ int32_t pad1 ;
+ int32_t pad2 ;
+ int32_t pad3 ;
+ int32_t pad4 ;
+ int32_t pad5 ;
+};
+
+Bool
+ephyrHostProxyDoForward (pointer a_request_buffer,
+ struct XReply *a_reply,
+ Bool a_do_swap) ;
+
+#endif /*__EPHYRHOSTPROXY_H__*/
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
new file mode 100644
index 000000000..562c2a4e8
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -0,0 +1,1004 @@
+/*
+ * 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 <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++) {
+ if (a_encodings[i].name) {
+ 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 ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
new file mode 100644
index 000000000..05ee38a03
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -0,0 +1,238 @@
+/*
+ * 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>
+ */
+#ifndef __EPHYRHOSTVIDEO_H__
+#define __EPHYRHOSTVIDEO_H__
+
+typedef void* EphyrHostXVAdaptor ;
+typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray ;
+
+typedef struct _EphyrHostVideoFormat {
+ char depth ;
+ short visual_class;
+} EphyrHostVideoFormat ;
+
+typedef struct _EphyrHostRational {
+ int numerator ;
+ int denominator ;
+} EphyrHostRational;
+
+typedef struct _EphyrHostEncoding {
+ int id ;
+ char *name ;
+ unsigned short width, height ;
+ EphyrHostRational rate ;
+} EphyrHostEncoding ;
+
+typedef struct _EphyrHostAttribute {
+ int flags;
+ int min_value;
+ int max_value;
+ char *name;
+} EphyrHostAttribute ;
+
+typedef struct _EphyrHostImageFormat {
+ int id; /* Unique descriptor for the format */
+ int type; /* XvRGB, XvYUV */
+ int byte_order; /* LSBFirst, MSBFirst */
+ char guid[16]; /* Globally Unique IDentifier */
+ int bits_per_pixel;
+ int format; /* XvPacked, XvPlanar */
+ int num_planes;
+
+ /* for RGB formats only */
+ int depth;
+ unsigned int red_mask;
+ unsigned int green_mask;
+ unsigned int blue_mask;
+
+ /* for YUV formats only */
+ unsigned int y_sample_bits;
+ unsigned int u_sample_bits;
+ unsigned int v_sample_bits;
+ unsigned int horz_y_period;
+ unsigned int horz_u_period;
+ unsigned int horz_v_period;
+ unsigned int vert_y_period;
+ unsigned int vert_u_period;
+ unsigned int vert_v_period;
+ char component_order[32]; /* eg. UYVY */
+ int scanline_order; /* XvTopToBottom, XvBottomToTop */
+} EphyrHostImageFormat ;
+
+typedef struct {
+ unsigned short x1, y1, x2, y2 ;
+} EphyrHostBox ;
+
+void ephyrHostXVInit (void) ;
+
+void ephyrHostFree (void *a_pointer) ;
+
+/*
+ * host adaptor array
+ */
+Bool ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
+void ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
+int ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
+EphyrHostXVAdaptor* ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+ int a_index) ;
+
+/*
+ * host adaptor
+ */
+
+char ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
+const char* ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
+EphyrHostVideoFormat* ephyrHostXVAdaptorGetVideoFormats
+ (const EphyrHostXVAdaptor *a_this,
+ int *a_nb_formats) ;
+int ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
+int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
+
+Bool ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+
+/*
+ * encoding
+ */
+Bool ephyrHostXVQueryEncodings (int a_port_id,
+ EphyrHostEncoding **a_encodings,
+ unsigned int *a_num_encodings) ;
+
+void ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+ int a_num_encodings) ;
+
+/*
+ * attribute
+ */
+Bool ephyrHostXVQueryPortAttributes (int a_port_id,
+ EphyrHostAttribute **a_attributes,
+ int *a_num_attributes) ;
+
+void ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
+/*
+ * image format
+ */
+
+Bool ephyrHostXVQueryImageFormats (int a_port_id,
+ EphyrHostImageFormat **a_formats,
+ int *a_num_format) ;
+/*
+ * Port Attribute Get/Set
+ */
+Bool ephyrHostXVSetPortAttribute (int a_port_id,
+ int a_atom,
+ int a_attr_value) ;
+Bool ephyrHostXVGetPortAttribute (int a_port_id,
+ int a_atom,
+ int *a_attr_value) ;
+/*
+ *size query
+ */
+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) ;
+
+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) ;
+/*
+ * atom
+ */
+Bool ephyrHostGetAtom (const char* a_name,
+ Bool a_create_if_not_exists,
+ int *a_atom) ;
+char* ephyrHostGetAtomName (int a_atom) ;
+
+/*
+ *PutImage
+ * (ignore clipping for now)
+ */
+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) ;
+
+/*
+ * Putvideo/PutStill/GetVideo
+ */
+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 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 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 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) ;
+
+/*
+ * StopVideo
+ */
+Bool ephyrHostXVStopVideo (int a_screen_num, int a_port_id) ;
+
+#endif /*__EPHYRHOSTVIDEO_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index a76da03b4..6196996a9 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -27,12 +27,21 @@
#include <kdrive-config.h>
#endif
#include "ephyr.h"
+#include "ephyrlog.h"
extern Window EphyrPreExistingHostWin;
extern Bool EphyrWantGrayScale;
extern Bool kdHasPointer;
extern Bool kdHasKbd;
+#ifdef GLXEXT
+extern Bool ephyrNoDRI;
+extern Bool noGlxVisualInit;
+#endif
+extern Bool ephyrNoXV;
+
+void processScreenArg (char *screen_size, char *parent_id) ;
+
void
InitCard (char *name)
{
@@ -90,29 +99,74 @@ ddxUseMsg (void)
KdUseMsg();
ErrorF("\nXephyr Option Usage:\n");
- ErrorF("-parent XID Use existing window as Xephyr root win\n");
- ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
- ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
- ErrorF("-grayscale Simulate 8bit grayscale\n");
- ErrorF("-fakexa Simulate acceleration using software rendering\n");
+ ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
+ ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
+ ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
+ ErrorF("-grayscale Simulate 8bit grayscale\n");
+ ErrorF("-fakexa Simulate acceleration using software rendering\n");
+ ErrorF("-verbosity <level> Set log verbosity level\n");
+#ifdef GLXEXT
+ ErrorF("-nodri do not use DRI\n");
+#endif
+ ErrorF("-noxv do not use XV\n");
ErrorF("\n");
exit(1);
}
+void
+processScreenArg (char *screen_size, char *parent_id)
+{
+ KdCardInfo *card;
+
+ InitCard (0); /*Put each screen on a separate card*/
+ card = KdCardInfoLast ();
+
+ if (card)
+ {
+ KdScreenInfo *screen;
+ unsigned long p_id = 0;
+
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, screen_size);
+
+ if (parent_id)
+ {
+ p_id = strtol (parent_id, NULL, 0);
+ }
+ EPHYR_DBG ("screen number:%d\n", screen->mynum) ;
+ hostx_add_screen (screen, p_id, screen->mynum);
+ }
+ else
+ {
+ ErrorF("No matching card found!\n");
+ }
+}
+
int
ddxProcessArgument (int argc, char **argv, int i)
{
- EPHYR_DBG("mark");
+ EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
if (!strcmp (argv[i], "-parent"))
{
- if(i+1 < argc)
+ if(i+1 < argc)
{
- hostx_use_preexisting_window(strtol(argv[i+1], NULL, 0));
+ processScreenArg ("100x100", argv[i+1]);
return 2;
- }
-
+ }
+
+ UseMsg();
+ exit(1);
+ }
+ else if (!strcmp (argv[i], "-screen"))
+ {
+ if ((i+1) < argc)
+ {
+ processScreenArg (argv[i+1], NULL);
+ return 2;
+ }
+
UseMsg();
exit(1);
}
@@ -139,6 +193,36 @@ ddxProcessArgument (int argc, char **argv, int i)
ephyrFuncs.finiAccel = ephyrDrawFini;
return 1;
}
+ else if (!strcmp (argv[i], "-verbosity"))
+ {
+ if(i+1 < argc && argv[i+1][0] != '-')
+ {
+ int verbosity=atoi (argv[i+1]) ;
+ LogSetParameter (XLOG_VERBOSITY, verbosity) ;
+ EPHYR_LOG ("set verbosiry to %d\n", verbosity) ;
+ return 2 ;
+ }
+ else
+ {
+ UseMsg() ;
+ exit(1) ;
+ }
+ }
+#ifdef GLXEXT
+ else if (!strcmp (argv[i], "-nodri"))
+ {
+ noGlxVisualInit = FALSE ;
+ ephyrNoDRI = TRUE ;
+ EPHYR_LOG ("no direct rendering enabled\n") ;
+ return 1 ;
+ }
+#endif
+ else if (!strcmp (argv[i], "-noxv"))
+ {
+ ephyrNoXV = TRUE ;
+ EPHYR_LOG ("no XVideo enabled\n") ;
+ return 1 ;
+ }
else if (argv[i][0] == ':')
{
hostx_set_display_name(argv[i]);
@@ -198,8 +282,10 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
Bool
ephyrCursorInit(ScreenPtr pScreen)
{
- miPointerInitialize(pScreen, &EphyrPointerSpriteFuncs,
- &kdPointerScreenFuncs, FALSE);
+ miPointerInitialize(pScreen,
+ &EphyrPointerSpriteFuncs,
+ &ephyrPointerScreenFuncs,
+ FALSE);
return TRUE;
}
diff --git a/hw/kdrive/ephyr/ephyrlog.h b/hw/kdrive/ephyr/ephyrlog.h
new file mode 100644
index 000000000..4c6435edd
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrlog.h
@@ -0,0 +1,67 @@
+/*
+ * 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>
+ */
+#ifndef __EPHYRLOG_H__
+#define __EPHYRLOG_H__
+
+#include <assert.h>
+#include "os.h"
+
+#ifdef NDEBUG
+/*we are not in debug mode*/
+#define EPHYR_LOG
+#define EPHYR_LOG_ERROR
+#endif /*NDEBUG*/
+
+#define ERROR_LOG_LEVEL 3
+#define INFO_LOG_LEVEL 4
+
+#ifndef EPHYR_LOG
+#define EPHYR_LOG(...) \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\
+ __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__)
+#endif /*nomadik_log*/
+
+#ifndef EPHYR_LOG_ERROR
+#define EPHYR_LOG_ERROR(...) \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\
+ __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__)
+#endif /*EPHYR_LOG_ERROR*/
+
+#ifndef EPHYR_RETURN_IF_FAIL
+#define EPHYR_RETURN_IF_FAIL(cond) \
+if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return;}
+#endif /*nomadik_return_if_fail*/
+
+#ifndef EPHYR_RETURN_VAL_IF_FAIL
+#define EPHYR_RETURN_VAL_IF_FAIL(cond,val) \
+if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return val;}
+#endif /*nomadik_return_val_if_fail*/
+
+#endif /*__EPHYRLOG_H__*/
diff --git a/hw/kdrive/ephyr/ephyrproxyext.c b/hw/kdrive/ephyr/ephyrproxyext.c
new file mode 100644
index 000000000..0c070f4c7
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrproxyext.c
@@ -0,0 +1,119 @@
+/*
+ * 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>
+ */
+
+/*
+ * \file
+ * This file defines a proxy extension that forwards requests.
+ * When a request to extension FOO is sent to Xephyr, that request is forwared
+ * to the host X, without even trying to know what the request means.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "ephyrproxyext.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "ephyrhostproxy.h"
+#include "hostx.h"
+
+static Bool ephyrProxyGetHostExtensionInfo (const char *a_ext_name,
+ int *a_major_opcode,
+ int *a_first_event,
+ int *a_first_error) ;
+
+static int ephyrProxyProcDispatch (ClientPtr client) ;
+
+static Bool
+ephyrProxyGetHostExtensionInfo (const char *a_ext_name,
+ int *a_major_opcode,
+ int *a_first_event,
+ int *a_first_error)
+{
+ return hostx_get_extension_info (a_ext_name, a_major_opcode,
+ a_first_event, a_first_error) ;
+}
+
+static int
+ephyrProxyProcDispatch (ClientPtr a_client)
+{
+ int res=BadImplementation ;
+ struct XReply reply ;
+
+ if (!ephyrHostProxyDoForward (a_client->requestBuffer, &reply, FALSE)) {
+ EPHYR_LOG_ERROR ("forwarding failed\n") ;
+ goto out ;
+ }
+ reply.sequence_number = a_client->sequence;
+ res = Success ;
+
+ WriteToClient(a_client, 32, (char *)&reply);
+
+out:
+ return res ;
+}
+
+static void
+ephyrProxyProcReset (ExtensionEntry *a_entry)
+{
+}
+
+Bool
+ephyrProxyExtensionInit (const char *a_extension_name)
+{
+ Bool is_ok = FALSE ;
+ int major_opcode=0, first_event=0, first_error=0;
+ ExtensionEntry *ext=NULL ;
+
+ if (!ephyrProxyGetHostExtensionInfo (a_extension_name,
+ &major_opcode,
+ &first_event,
+ &first_error)) {
+ EPHYR_LOG ("failed to query extension %s from host\n", a_extension_name) ;
+ goto out;
+ }
+ ext = AddExtension ((char*)a_extension_name, 0, 0,
+ ephyrProxyProcDispatch,
+ ephyrProxyProcDispatch,
+ ephyrProxyProcReset,
+ StandardMinorOpcode) ;
+ if (!ext) {
+ EPHYR_LOG_ERROR ("failed to add the extension\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrproxyext.h b/hw/kdrive/ephyr/ephyrproxyext.h
new file mode 100644
index 000000000..e52f8d887
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrproxyext.h
@@ -0,0 +1,34 @@
+/*
+ * 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>
+ */
+#ifndef __EPHYRPROXYEXT_H__
+#define __EPHYRPROXYEXT_H__
+
+Bool ephyrProxyExtensionInit (const char *a_extension_name) ;
+
+#endif /*__EPHYRPROXYEXT_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
new file mode 100644
index 000000000..bfe4d7223
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -0,0 +1,1278 @@
+/*
+ * 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)
+{
+ 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[0].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 ;
+ }
+ if (a_this->adaptors) {
+ 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:
+ if (registered_adaptors) {
+ xfree (registered_adaptors) ;
+ registered_adaptors = NULL ;
+ }
+ if (adaptors) {
+ 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: %#x, offsets: %#x\n",
+ *a_w, *a_h, (unsigned int)a_pitches, (unsigned int)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 ;
+}
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 36d3cbd46..b5ffdd075 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -23,6 +23,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
#include "hostx.h"
#include <stdlib.h>
@@ -40,6 +44,17 @@
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
+#ifdef XEPHYR_DRI
+#include <GL/glx.h>
+#endif /*XEPHYR_DRI*/
+#include "ephyrlog.h"
+
+#ifdef XEPHYR_DRI
+extern Bool XF86DRIQueryExtension (Display *dpy,
+ int *event_basep,
+ int *error_basep);
+#endif
/*
* All xlib calls go here, which gets built as its own .a .
@@ -47,33 +62,44 @@
* to get clobbered.
*/
+struct EphyrHostScreen
+{
+ Window win;
+ Window win_pre_existing; /* Set via -parent option like xnest */
+ XImage *ximg;
+ int win_width, win_height;
+ int server_depth;
+ unsigned char *fb_data; /* only used when host bpp != server bpp */
+ XShmSegmentInfo shminfo;
+
+ void *info; /* Pointer to the screen this is associated with */
+ int mynum; /* Screen number */
+};
+
struct EphyrHostXVars
{
char *server_dpy_name;
Display *dpy;
int screen;
Visual *visual;
- Window win, winroot;
- Window win_pre_existing; /* Set via -parent option like xnest */
+ Window winroot;
GC gc;
int depth;
- int server_depth;
- XImage *ximg;
- int win_width, win_height;
Bool use_host_cursor;
Bool use_fullscreen;
Bool have_shm;
+ int n_screens;
+ struct EphyrHostScreen *screens;
+
long damage_debug_msec;
- unsigned char *fb_data; /* only used when host bpp != server bpp */
unsigned long cmap[256];
-
- XShmSegmentInfo shminfo;
};
/* memset ( missing> ) instead of below */
-static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+/*static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};*/
+static EphyrHostXVars HostX;
static int HostXWantDamageDebug = 0;
@@ -89,8 +115,22 @@ hostx_set_fullscreen_hint(void);
static int trapped_error_code = 0;
static int (*old_error_handler) (Display *d, XErrorEvent *e);
-#define host_depth_matches_server() (HostX.depth == HostX.server_depth)
+#define host_depth_matches_server(_vars) (HostX.depth == (_vars)->server_depth)
+static struct EphyrHostScreen *
+host_screen_from_screen_info (EphyrScreenInfo *screen)
+{
+ int i;
+
+ for (i = 0 ; i < HostX.n_screens ; i++)
+ {
+ if ( HostX.screens[i].info == screen)
+ {
+ return &HostX.screens[i];
+ }
+ }
+ return NULL;
+}
static int
error_handler(Display *display,
@@ -115,13 +155,16 @@ hostx_errors_untrap(void)
}
int
-hostx_want_screen_size(int *width, int *height)
+hostx_want_screen_size (EphyrScreenInfo screen, int *width, int *height )
{
- if (HostX.win_pre_existing != None
- || HostX.use_fullscreen == True)
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen &&
+ (host_screen->win_pre_existing != None ||
+ HostX.use_fullscreen == True))
{
- *width = HostX.win_width;
- *height = HostX.win_height;
+ *width = host_screen->win_width;
+ *height = host_screen->win_height;
return 1;
}
@@ -129,100 +172,140 @@ hostx_want_screen_size(int *width, int *height)
}
void
-hostx_set_display_name(char *name)
+hostx_add_screen (EphyrScreenInfo screen,
+ unsigned long win_id,
+ int screen_num)
+{
+ int index = HostX.n_screens;
+
+ HostX.n_screens += 1;
+ HostX.screens = realloc (HostX.screens,
+ HostX.n_screens * sizeof(struct EphyrHostScreen));
+ memset (&HostX.screens[index], 0, sizeof (struct EphyrHostScreen));
+
+ HostX.screens[index].info = screen;
+ HostX.screens[index].win_pre_existing = win_id;
+}
+
+
+void
+hostx_set_display_name (char *name)
{
- HostX.server_dpy_name = strdup(name);
+ HostX.server_dpy_name = strdup (name);
}
void
-hostx_set_win_title(char *extra_text)
+hostx_set_screen_number(EphyrScreenInfo screen, int number)
{
- char buf[256];
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+ if (host_screen) {
+ host_screen->mynum = number;
+ hostx_set_win_title (host_screen->info, "") ;
+ }}
- snprintf(buf, 256, "Xephyr on %s %s",
- HostX.server_dpy_name,
- (extra_text != NULL) ? extra_text : "");
+void
+hostx_set_win_title (EphyrScreenInfo screen, char *extra_text)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+#define BUF_LEN 256
+ char buf[BUF_LEN+1];
+
+ if (!host_screen)
+ return;
+
+ memset (buf, 0, BUF_LEN+1) ;
+ snprintf (buf, BUF_LEN, "Xephyr on %s.%d %s",
+ HostX.server_dpy_name,
+ host_screen->mynum,
+ (extra_text != NULL) ? extra_text : "");
- XStoreName(HostX.dpy, HostX.win, buf);
+ XStoreName (HostX.dpy, host_screen->win, buf);
}
int
-hostx_want_host_cursor(void)
+hostx_want_host_cursor (void)
{
return HostX.use_host_cursor;
}
void
-hostx_use_host_cursor(void)
+hostx_use_host_cursor (void)
{
HostX.use_host_cursor = True;
}
int
-hostx_want_preexisting_window(void)
+hostx_want_preexisting_window (EphyrScreenInfo screen)
{
- if (HostX.win_pre_existing)
- return 1;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen && host_screen->win_pre_existing)
+ {
+ return 1;
+ }
else
+ {
return 0;
+ }
}
void
-hostx_use_fullscreen(void)
+hostx_use_fullscreen (void)
{
HostX.use_fullscreen = True;
}
int
-hostx_want_fullscreen(void)
+hostx_want_fullscreen (void)
{
return HostX.use_fullscreen;
}
static void
-hostx_set_fullscreen_hint(void)
+hostx_set_fullscreen_hint (void)
{
Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN;
+ int index;
atom_WINDOW_STATE
= XInternAtom(HostX.dpy, "_NET_WM_STATE", False);
atom_WINDOW_STATE_FULLSCREEN
= XInternAtom(HostX.dpy, "_NET_WM_STATE_FULLSCREEN",False);
- XChangeProperty(HostX.dpy, HostX.win,
- atom_WINDOW_STATE, XA_ATOM, 32,
- PropModeReplace,
- (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ XChangeProperty (HostX.dpy, HostX.screens[index].win,
+ atom_WINDOW_STATE, XA_ATOM, 32,
+ PropModeReplace,
+ (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+ }
}
-void
-hostx_use_preexisting_window(unsigned long win_id)
-{
- HostX.win_pre_existing = win_id;
-}
static void
-hostx_toggle_damage_debug(void)
+hostx_toggle_damage_debug (void)
{
HostXWantDamageDebug ^= 1;
}
-void
-hostx_handle_signal(int signum)
+void
+hostx_handle_signal (int signum)
{
hostx_toggle_damage_debug();
- EPHYR_DBG("Signal caught. Damage Debug:%i\n", HostXWantDamageDebug);
+ EPHYR_DBG ("Signal caught. Damage Debug:%i\n",
+ HostXWantDamageDebug);
}
int
-hostx_init(void)
+hostx_init (void)
{
XSetWindowAttributes attr;
Cursor empty_cursor;
Pixmap cursor_pxm;
XColor col;
+ int index;
- attr.event_mask =
+ attr.event_mask =
ButtonPressMask
|ButtonReleaseMask
|PointerMotionMask
@@ -233,126 +316,142 @@ hostx_init(void)
EPHYR_DBG("mark");
if ((HostX.dpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
- {
- fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
- exit(1);
- }
+ {
+ fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
+ exit(1);
+ }
HostX.screen = DefaultScreen(HostX.dpy);
HostX.winroot = RootWindow(HostX.dpy, HostX.screen);
HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL);
HostX.depth = DefaultDepth(HostX.dpy, HostX.screen);
- HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
-
- HostX.server_depth = HostX.depth;
-
- if (HostX.win_pre_existing != None)
- {
- Status result;
- XWindowAttributes prewin_attr;
+ HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
- /* Get screen size from existing window */
-
- hostx_errors_trap();
-
- result = XGetWindowAttributes(HostX.dpy,
- HostX.win_pre_existing,
- &prewin_attr);
-
-
- if (hostx_errors_untrap() || !result)
- {
- fprintf(stderr, "\nXephyr -parent window' does not exist!\n");
- exit(1);
- }
-
- HostX.win_width = prewin_attr.width;
- HostX.win_height = prewin_attr.height;
-
- HostX.win = XCreateWindow(HostX.dpy,
- HostX.win_pre_existing,
- 0,0,HostX.win_width,HostX.win_height,
- 0,
- CopyFromParent,
- CopyFromParent,
- CopyFromParent,
- CWEventMask,
- &attr);
- }
- else
+ for (index = 0 ; index < HostX.n_screens ; index++)
{
- HostX.win = XCreateWindow(HostX.dpy,
- HostX.winroot,
- 0,0,100,100, /* will resize */
- 0,
- CopyFromParent,
- CopyFromParent,
- CopyFromParent,
- CWEventMask,
- &attr);
-
- hostx_set_win_title("( ctrl+shift grabs mouse and keyboard )");
-
- if (HostX.use_fullscreen)
- {
- HostX.win_width = DisplayWidth(HostX.dpy, HostX.screen);
- HostX.win_height = DisplayHeight(HostX.dpy, HostX.screen);
-
- hostx_set_fullscreen_hint();
- }
+ struct EphyrHostScreen *host_screen = &HostX.screens[index];
+
+ host_screen->server_depth = HostX.depth;
+ if (host_screen->win_pre_existing != None)
+ {
+ Status result;
+ XWindowAttributes prewin_attr;
+
+ /* Get screen size from existing window */
+
+ hostx_errors_trap();
+
+ result = XGetWindowAttributes (HostX.dpy,
+ host_screen->win_pre_existing,
+ &prewin_attr);
+
+
+ if (hostx_errors_untrap() || !result)
+ {
+ fprintf (stderr, "\nXephyr -parent window' does not exist!\n");
+ exit (1);
+ }
+
+ host_screen->win_width = prewin_attr.width;
+ host_screen->win_height = prewin_attr.height;
+
+ host_screen->win = XCreateWindow (HostX.dpy,
+ host_screen->win_pre_existing,
+ 0,0,
+ host_screen->win_width,
+ host_screen->win_height,
+ 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWEventMask,
+ &attr);
+ }
+ else
+ {
+ host_screen->win = XCreateWindow (HostX.dpy,
+ HostX.winroot,
+ 0,0,100,100, /* will resize */
+ 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWEventMask,
+ &attr);
+
+ hostx_set_win_title (host_screen->info,
+ "(ctrl+shift grabs mouse and keyboard)");
+
+ if (HostX.use_fullscreen)
+ {
+ host_screen->win_width = DisplayWidth(HostX.dpy, HostX.screen);
+ host_screen->win_height = DisplayHeight(HostX.dpy, HostX.screen);
+
+ hostx_set_fullscreen_hint();
+ }
+ }
}
- XParseColor(HostX.dpy, DefaultColormap(HostX.dpy,HostX.screen), "red", &col);
- XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col);
- XSetForeground(HostX.dpy, HostX.gc, col.pixel);
+ XParseColor (HostX.dpy, DefaultColormap (HostX.dpy,HostX.screen),
+ "red", &col);
+ XAllocColor (HostX.dpy, DefaultColormap (HostX.dpy, HostX.screen),
+ &col);
+ XSetForeground (HostX.dpy, HostX.gc, col.pixel);
- if (!hostx_want_host_cursor())
+ if (!hostx_want_host_cursor ())
{
/* Ditch the cursor, we provide our 'own' */
cursor_pxm = XCreatePixmap (HostX.dpy, HostX.winroot, 1, 1, 1);
memset (&col, 0, sizeof (col));
- empty_cursor = XCreatePixmapCursor (HostX.dpy,
- cursor_pxm, cursor_pxm,
- &col, &col, 1, 1);
- XDefineCursor (HostX.dpy, HostX.win, empty_cursor);
+ empty_cursor = XCreatePixmapCursor (HostX.dpy,
+ cursor_pxm, cursor_pxm,
+ &col, &col, 1, 1);
+ for ( index = 0 ; index < HostX.n_screens ; index++ )
+ {
+ XDefineCursor (HostX.dpy,
+ HostX.screens[index].win,
+ empty_cursor);
+ }
XFreePixmap (HostX.dpy, cursor_pxm);
}
- HostX.ximg = NULL;
-
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ HostX.screens[index].ximg = NULL;
+ }
/* Try to get share memory ximages for a little bit more speed */
- if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM"))
+ if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM"))
{
fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
HostX.have_shm = False;
- }
- else
- {
+ }
+ else
+ {
/* Really really check we have shm - better way ?*/
- XShmSegmentInfo shminfo;
+ XShmSegmentInfo shminfo;
- HostX.have_shm = True;
+ HostX.have_shm = True;
- shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777);
- shminfo.shmaddr=shmat(shminfo.shmid,0,0);
- shminfo.readOnly=True;
+ shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777);
+ shminfo.shmaddr=shmat(shminfo.shmid,0,0);
+ shminfo.readOnly=True;
- hostx_errors_trap();
-
- XShmAttach(HostX.dpy, &shminfo);
- XSync(HostX.dpy, False);
+ hostx_errors_trap();
- if (hostx_errors_untrap())
- {
- fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
- HostX.have_shm = False;
- }
+ XShmAttach(HostX.dpy, &shminfo);
+ XSync(HostX.dpy, False);
- shmdt(shminfo.shmaddr);
- shmctl(shminfo.shmid, IPC_RMID, 0);
- }
+ if (hostx_errors_untrap())
+ {
+ fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
+ HostX.have_shm = False;
+ }
+
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+}
XFlush(HostX.dpy);
@@ -360,10 +459,10 @@ hostx_init(void)
HostX.damage_debug_msec = 20000; /* 1/50 th of a second */
- if (getenv("XEPHYR_PAUSE"))
+ if (getenv ("XEPHYR_PAUSE"))
{
- HostX.damage_debug_msec = strtol(getenv("XEPHYR_PAUSE"), NULL, 0);
- EPHYR_DBG("pause is %li\n", HostX.damage_debug_msec);
+ HostX.damage_debug_msec = strtol (getenv ("XEPHYR_PAUSE"), NULL, 0);
+ EPHYR_DBG ("pause is %li\n", HostX.damage_debug_msec);
}
return 1;
@@ -376,38 +475,54 @@ hostx_get_depth (void)
}
int
-hostx_get_server_depth (void)
+hostx_get_server_depth (EphyrScreenInfo screen)
{
- return HostX.server_depth;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ return (host_screen ? host_screen->server_depth : 0);
}
void
-hostx_set_server_depth(int depth)
+hostx_set_server_depth (EphyrScreenInfo screen, int depth)
{
- HostX.server_depth = depth;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen)
+ host_screen->server_depth = depth;
}
int
-hostx_get_bpp(void)
+hostx_get_bpp (EphyrScreenInfo screen)
{
- if (host_depth_matches_server())
- return HostX.visual->bits_per_rgb;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (!host_screen)
+ return 0;
+
+ if (host_depth_matches_server (host_screen))
+ return HostX.visual->bits_per_rgb;
else
- return HostX.server_depth; /* XXX correct ? */
+ return host_screen->server_depth; /*XXX correct ?*/
}
void
-hostx_get_visual_masks (CARD32 *rmsk,
- CARD32 *gmsk,
+hostx_get_visual_masks (EphyrScreenInfo screen,
+ CARD32 *rmsk,
+ CARD32 *gmsk,
CARD32 *bmsk)
{
- if (host_depth_matches_server())
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (!host_screen)
+ return;
+
+ if (host_depth_matches_server(host_screen))
{
*rmsk = HostX.visual->red_mask;
*gmsk = HostX.visual->green_mask;
*bmsk = HostX.visual->blue_mask;
}
- else if (HostX.server_depth == 16)
+ else if (host_screen->server_depth == 16)
{
/* Assume 16bpp 565 */
*rmsk = 0xf800;
@@ -423,9 +538,9 @@ hostx_get_visual_masks (CARD32 *rmsk,
}
void
-hostx_set_cmap_entry(unsigned char idx,
- unsigned char r,
- unsigned char g,
+hostx_set_cmap_entry(unsigned char idx,
+ unsigned char r,
+ unsigned char g,
unsigned char b)
{
/* XXX Will likely break for 8 on 16, not sure if this is correct */
@@ -445,15 +560,25 @@ hostx_set_cmap_entry(unsigned char idx,
* by fakexa for storing offscreen pixmap data.
*/
void*
-hostx_screen_init (int width, int height, int buffer_height)
+hostx_screen_init (EphyrScreenInfo screen,
+ int width, int height,
+ int buffer_height)
{
int bitmap_pad;
Bool shm_success = False;
XSizeHints *size_hints;
- EPHYR_DBG("mark");
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+ if (!host_screen)
+ {
+ fprintf (stderr, "%s: Error in accessing hostx data\n", __func__ );
+ exit(1);
+ }
- if (HostX.ximg != NULL)
+ EPHYR_DBG ("host_screen=%p wxh=%dx%d, buffer_height=%d",
+ host_screen, width, height, buffer_height);
+
+ if (host_screen->ximg != NULL)
{
/* Free up the image data if previously used
* i.ie called by server reset
@@ -461,47 +586,48 @@ hostx_screen_init (int width, int height, int buffer_height)
if (HostX.have_shm)
{
- XShmDetach(HostX.dpy, &HostX.shminfo);
- XDestroyImage (HostX.ximg);
- shmdt(HostX.shminfo.shmaddr);
- shmctl(HostX.shminfo.shmid, IPC_RMID, 0);
+ XShmDetach(HostX.dpy, &host_screen->shminfo);
+ XDestroyImage (host_screen->ximg);
+ shmdt(host_screen->shminfo.shmaddr);
+ shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
}
else
{
- if (HostX.ximg->data)
+ if (host_screen->ximg->data)
{
- free(HostX.ximg->data);
- HostX.ximg->data = NULL;
+ free(host_screen->ximg->data);
+ host_screen->ximg->data = NULL;
}
- XDestroyImage(HostX.ximg);
+ XDestroyImage(host_screen->ximg);
}
}
if (HostX.have_shm)
{
- HostX.ximg = XShmCreateImage(HostX.dpy, HostX.visual, HostX.depth,
- ZPixmap, NULL, &HostX.shminfo,
- width, buffer_height );
-
- HostX.shminfo.shmid = shmget(IPC_PRIVATE,
- HostX.ximg->bytes_per_line * buffer_height,
- IPC_CREAT|0777);
- HostX.shminfo.shmaddr = HostX.ximg->data = shmat(HostX.shminfo.shmid,
- 0, 0);
-
- if (HostX.ximg->data == (char *)-1)
+ host_screen->ximg = XShmCreateImage (HostX.dpy, HostX.visual, HostX.depth,
+ ZPixmap, NULL, &host_screen->shminfo,
+ width, buffer_height );
+
+ host_screen->shminfo.shmid =
+ shmget(IPC_PRIVATE,
+ host_screen->ximg->bytes_per_line * buffer_height,
+ IPC_CREAT|0777);
+ host_screen->ximg->data = shmat(host_screen->shminfo.shmid, 0, 0);
+ host_screen->shminfo.shmaddr = host_screen->ximg->data;
+
+ if (host_screen->ximg->data == (char *)-1)
{
EPHYR_DBG("Can't attach SHM Segment, falling back to plain XImages");
HostX.have_shm = False;
- XDestroyImage(HostX.ximg);
- shmctl(HostX.shminfo.shmid, IPC_RMID, 0);
+ XDestroyImage(host_screen->ximg);
+ shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
}
else
{
- EPHYR_DBG("SHM segment attached");
- HostX.shminfo.readOnly = False;
- XShmAttach(HostX.dpy, &HostX.shminfo);
+ EPHYR_DBG("SHM segment attached %p", host_screen->shminfo.shmaddr);
+ host_screen->shminfo.readOnly = False;
+ XShmAttach(HostX.dpy, &host_screen->shminfo);
shm_success = True;
}
}
@@ -509,63 +635,74 @@ hostx_screen_init (int width, int height, int buffer_height)
if (!shm_success)
{
bitmap_pad = ( HostX.depth > 16 )? 32 : (( HostX.depth > 8 )? 16 : 8 );
-
- HostX.ximg = XCreateImage( HostX.dpy,
- HostX.visual,
- HostX.depth,
- ZPixmap, 0, 0,
- width,
- buffer_height,
- bitmap_pad,
- 0);
- HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * buffer_height );
+ EPHYR_DBG("Creating image %dx%d for screen host_screen=%p\n",
+ width, buffer_height, host_screen );
+ host_screen->ximg = XCreateImage (HostX.dpy,
+ HostX.visual,
+ HostX.depth,
+ ZPixmap, 0, 0,
+ width,
+ buffer_height,
+ bitmap_pad,
+ 0);
+
+ host_screen->ximg->data =
+ malloc (host_screen->ximg->bytes_per_line * buffer_height);
}
-
- XResizeWindow(HostX.dpy, HostX.win, width, height);
+ XResizeWindow (HostX.dpy, host_screen->win, width, height);
/* Ask the WM to keep our size static */
size_hints = XAllocSizeHints();
size_hints->max_width = size_hints->min_width = width;
size_hints->max_height = size_hints->min_height = height;
size_hints->flags = PMinSize|PMaxSize;
- XSetWMNormalHints(HostX.dpy, HostX.win, size_hints);
+ XSetWMNormalHints(HostX.dpy, host_screen->win, size_hints);
XFree(size_hints);
- XMapWindow(HostX.dpy, HostX.win);
+ XMapWindow(HostX.dpy, host_screen->win);
XSync(HostX.dpy, False);
- HostX.win_width = width;
- HostX.win_height = height;
+ host_screen->win_width = width;
+ host_screen->win_height = height;
- if (host_depth_matches_server())
+ if (host_depth_matches_server(host_screen))
{
EPHYR_DBG("Host matches server");
- return HostX.ximg->data;
+ return host_screen->ximg->data;
}
else
{
- EPHYR_DBG("server bpp %i", HostX.server_depth>>3);
- HostX.fb_data = malloc(width*buffer_height*(HostX.server_depth>>3));
- return HostX.fb_data;
+ EPHYR_DBG("server bpp %i", host_screen->server_depth>>3);
+ host_screen->fb_data = malloc(width*buffer_height*(host_screen->server_depth>>3));
+ return host_screen->fb_data;
}
}
+static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+ int x, int y,
+ int width, int height);
+
void
-hostx_paint_rect(int sx, int sy,
- int dx, int dy,
- int width, int height)
+hostx_paint_rect (EphyrScreenInfo screen,
+ int sx, int sy,
+ int dx, int dy,
+ int width, int height)
{
- /*
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ;
+
+ /*
* Copy the image data updated by the shadow layer
* on to the window
*/
if (HostXWantDamageDebug)
{
- hostx_paint_debug_rect(dx, dy, width, height);
+ hostx_paint_debug_rect(host_screen, dx, dy, width, height);
}
/*
@@ -580,22 +717,23 @@ hostx_paint_rect(int sx, int sy,
* ... and it will be slower than the matching depth case.
*/
- if (!host_depth_matches_server())
+ if (!host_depth_matches_server(host_screen))
{
- int x,y,idx, bytes_per_pixel = (HostX.server_depth>>3);
+ int x,y,idx, bytes_per_pixel = (host_screen->server_depth>>3);
unsigned char r,g,b;
unsigned long host_pixel;
+ EPHYR_DBG("Unmatched host depth host_screen=%p\n", host_screen);
for (y=sy; y<sy+height; y++)
for (x=sx; x<sx+width; x++)
{
- idx = (HostX.win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
-
- switch (HostX.server_depth)
+ idx = (host_screen->win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
+
+ switch (host_screen->server_depth)
{
case 16:
{
- unsigned short pixel = *(unsigned short*)(HostX.fb_data+idx);
+ unsigned short pixel = *(unsigned short*)(host_screen->fb_data+idx);
r = ((pixel & 0xf800) >> 8);
g = ((pixel & 0x07e0) >> 3);
@@ -603,13 +741,13 @@ hostx_paint_rect(int sx, int sy,
host_pixel = (r << 16) | (g << 8) | (b);
- XPutPixel(HostX.ximg, x, y, host_pixel);
+ XPutPixel(host_screen->ximg, x, y, host_pixel);
break;
}
case 8:
{
- unsigned char pixel = *(unsigned char*)(HostX.fb_data+idx);
- XPutPixel(HostX.ximg, x, y, HostX.cmap[pixel]);
+ unsigned char pixel = *(unsigned char*)(host_screen->fb_data+idx);
+ XPutPixel(host_screen->ximg, x, y, HostX.cmap[pixel]);
break;
}
default:
@@ -620,21 +758,23 @@ hostx_paint_rect(int sx, int sy,
if (HostX.have_shm)
{
- XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
- sx, sy, dx, dy, width, height, False);
+ XShmPutImage (HostX.dpy, host_screen->win,
+ HostX.gc, host_screen->ximg,
+ sx, sy, dx, dy, width, height, False);
}
else
{
- XPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
- sx, sy, dx, dy, width, height);
+ XPutImage (HostX.dpy, host_screen->win, HostX.gc, host_screen->ximg,
+ sx, sy, dx, dy, width, height);
}
- XSync(HostX.dpy, False);
+ XSync (HostX.dpy, False);
}
-void
-hostx_paint_debug_rect(int x, int y,
- int width, int height)
+static void
+hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+ int x, int y,
+ int width, int height)
{
struct timespec tspec;
@@ -646,8 +786,8 @@ hostx_paint_debug_rect(int x, int y,
/* fprintf(stderr, "Xephyr updating: %i+%i %ix%i\n", x, y, width, height); */
- XFillRectangle(HostX.dpy, HostX.win, HostX.gc, x, y, width,height);
- XSync(HostX.dpy, False);
+ XFillRectangle (HostX.dpy, host_screen->win, HostX.gc, x, y, width,height);
+ XSync (HostX.dpy, False);
/* nanosleep seems to work better than usleep for me... */
nanosleep(&tspec, NULL);
@@ -660,14 +800,14 @@ hostx_load_keymap(void)
int host_width, min_keycode, max_keycode, width;
int i,j;
- XDisplayKeycodes(HostX.dpy, &min_keycode, &max_keycode);
+ XDisplayKeycodes (HostX.dpy, &min_keycode, &max_keycode);
- EPHYR_DBG("min: %d, max: %d", min_keycode, max_keycode);
+ EPHYR_DBG ("min: %d, max: %d", min_keycode, max_keycode);
- keymap = XGetKeyboardMapping(HostX.dpy,
- min_keycode,
- max_keycode - min_keycode + 1,
- &host_width);
+ keymap = XGetKeyboardMapping (HostX.dpy,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &host_width);
/* Try and copy the hosts keymap into our keymap to avoid loads
* of messing around.
@@ -688,7 +828,7 @@ hostx_load_keymap(void)
ephyrKeySyms.map[(i*width)+j] = (CARD32) keymap[(i*host_width) + j];
EPHYR_DBG("keymap width, host:%d kdrive:%d", host_width, width);
-
+
ephyrKeySyms.minKeyCode = min_keycode;
ephyrKeySyms.maxKeyCode = max_keycode;
ephyrKeySyms.mapWidth = width;
@@ -696,11 +836,26 @@ hostx_load_keymap(void)
XFree(keymap);
}
+static struct EphyrHostScreen *
+host_screen_from_window (Window w)
+{
+ int index;
+
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ if (HostX.screens[index].win == w)
+ {
+ return &HostX.screens[index];
+ }
+ }
+ return NULL;
+}
+
int
hostx_get_event(EphyrHostXEvent *ev)
{
XEvent xev;
- static Bool grabbed;
+ static int grabbed_screen = -1;
if (XPending(HostX.dpy))
{
@@ -710,15 +865,27 @@ hostx_get_event(EphyrHostXEvent *ev)
{
case Expose:
/* Not so great event compression, but works ok */
- while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window,
+ while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window,
Expose, &xev));
- hostx_paint_rect(0, 0, 0, 0, HostX.win_width, HostX.win_height);
+ {
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xexpose.window);
+ hostx_paint_rect (host_screen->info, 0, 0, 0, 0,
+ host_screen->win_width,
+ host_screen->win_height);
+ }
return 0;
case MotionNotify:
- ev->type = EPHYR_EV_MOUSE_MOTION;
- ev->data.mouse_motion.x = xev.xmotion.x;
- ev->data.mouse_motion.y = xev.xmotion.y;
+ {
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xmotion.window);
+
+ ev->type = EPHYR_EV_MOUSE_MOTION;
+ ev->data.mouse_motion.x = xev.xmotion.x;
+ ev->data.mouse_motion.y = xev.xmotion.y;
+ ev->data.mouse_motion.screen = (host_screen ? host_screen->mynum : -1);
+ }
return 1;
case ButtonPress:
@@ -750,29 +917,35 @@ hostx_get_event(EphyrHostXEvent *ev)
|| XKeycodeToKeysym(HostX.dpy,xev.xkey.keycode,0) == XK_Shift_R)
&& (xev.xkey.state & ControlMask))
{
- if (grabbed)
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xexpose.window);
+
+ if (grabbed_screen != -1)
{
XUngrabKeyboard (HostX.dpy, CurrentTime);
XUngrabPointer (HostX.dpy, CurrentTime);
- grabbed = False;
- hostx_set_win_title("( ctrl+shift grabs mouse and keyboard )");
- }
- else
+ grabbed_screen = -1;
+ hostx_set_win_title (host_screen->info,
+ "(ctrl+shift grabs mouse and keyboard)");
+ }
+ else
{
/* Attempt grab */
- if (XGrabKeyboard (HostX.dpy, HostX.win, True,
+ if (XGrabKeyboard (HostX.dpy, host_screen->win, True,
GrabModeAsync,
GrabModeAsync,
CurrentTime) == 0)
{
- if (XGrabPointer (HostX.dpy, HostX.win, True,
+ if (XGrabPointer (HostX.dpy, host_screen->win, True,
NoEventMask,
GrabModeAsync,
GrabModeAsync,
- HostX.win, None, CurrentTime) == 0)
+ host_screen->win, None, CurrentTime) == 0)
{
- grabbed = True;
- hostx_set_win_title("( ctrl+shift releases mouse and keyboard )");
+ grabbed_screen = host_screen->mynum;
+ hostx_set_win_title
+ (host_screen->info,
+ "(ctrl+shift releases mouse and keyboard)");
}
else /* Failed pointer grabm ungrab keyboard */
XUngrabKeyboard (HostX.dpy, CurrentTime);
@@ -798,3 +971,385 @@ hostx_get_event(EphyrHostXEvent *ev)
return 0;
}
+void*
+hostx_get_display(void)
+{
+ return HostX.dpy ;
+}
+
+int
+hostx_get_window (int a_screen_number)
+{
+ if (a_screen_number < 0 || a_screen_number >= HostX.n_screens) {
+ EPHYR_LOG_ERROR ("bad screen number:%d\n", a_screen_number) ;
+ return 0;
+ }
+ return HostX.screens[a_screen_number].win ;
+}
+
+int
+hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attrs)
+{
+ XWindowAttributes attrs ;
+
+ memset (&attrs, 0, sizeof (attrs)) ;
+
+ if (!XGetWindowAttributes (hostx_get_display (),
+ a_window,
+ &attrs)) {
+ return FALSE ;
+ }
+ a_attrs->x = attrs.x ;
+ a_attrs->y = attrs.y ;
+ a_attrs->width = attrs.width ;
+ a_attrs->height = attrs.height ;
+ if (attrs.visual)
+ a_attrs->visualid = attrs.visual->visualid ;
+ return TRUE ;
+}
+
+int
+hostx_get_extension_info (const char *a_ext_name,
+ int *a_major_opcode,
+ int *a_first_event,
+ int *a_first_error)
+{
+ if (!a_ext_name || !a_major_opcode || !a_first_event || !a_first_error)
+ return 0 ;
+ if (!XQueryExtension (HostX.dpy,
+ a_ext_name,
+ a_major_opcode,
+ a_first_event,
+ a_first_error))
+ {
+ return 0 ;
+ }
+ return 1 ;
+}
+
+int
+hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
+ int *a_num_entries)
+{
+ Display *dpy=hostx_get_display () ;
+ Bool is_ok=False ;
+ XVisualInfo templ, *visuals=NULL;
+ EphyrHostVisualInfo *host_visuals=NULL ;
+ int nb_items=0, i=0;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_visuals && a_num_entries && dpy,
+ False) ;
+ EPHYR_LOG ("enter\n") ;
+ memset (&templ, 0, sizeof (templ)) ;
+ visuals = XGetVisualInfo (dpy, VisualNoMask, &templ, &nb_items) ;
+ if (!visuals) {
+ EPHYR_LOG_ERROR ("host does not advertise any visual\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host advertises %d visuals\n", nb_items) ;
+ host_visuals = calloc (nb_items, sizeof (EphyrHostVisualInfo)) ;
+ for (i=0; i<nb_items; i++) {
+ host_visuals[i].visualid = visuals[i].visualid ;
+ host_visuals[i].screen = visuals[i].screen ;
+ host_visuals[i].depth = visuals[i].depth ;
+ host_visuals[i].class = visuals[i].class ;
+ host_visuals[i].red_mask = visuals[i].red_mask ;
+ host_visuals[i].green_mask = visuals[i].green_mask ;
+ host_visuals[i].blue_mask = visuals[i].blue_mask ;
+ host_visuals[i].colormap_size = visuals[i].colormap_size ;
+ host_visuals[i].bits_per_rgb = visuals[i].bits_per_rgb ;
+ }
+ *a_visuals = host_visuals ;
+ *a_num_entries = nb_items;
+ host_visuals=NULL;
+
+ is_ok = TRUE;
+out:
+ if (visuals) {
+ XFree (visuals) ;
+ visuals = NULL;
+ }
+ if (host_visuals) {
+ free (host_visuals) ;
+ host_visuals = NULL;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+
+}
+
+typedef struct {
+ int is_valid ;
+ int local_id ;
+ int remote_id ;
+} ResourcePair ;
+
+#define RESOURCE_PEERS_SIZE 1024*10
+static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
+
+
+int
+hostx_create_window (int a_screen_number,
+ EphyrBox *a_geometry,
+ int a_visual_id,
+ int *a_host_peer /*out parameter*/)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy=hostx_get_display () ;
+ XVisualInfo *visual_info=NULL, visual_info_templ;
+ int visual_mask=VisualIDMask ;
+ Window win=None ;
+ int nb_visuals=0, winmask=0;
+ XSetWindowAttributes attrs;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geometry, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ /*get visual*/
+ memset (&visual_info, 0, sizeof (visual_info)) ;
+ visual_info_templ.visualid = a_visual_id ;
+ visual_info = XGetVisualInfo (dpy, visual_mask,
+ &visual_info_templ,
+ &nb_visuals) ;
+ if (!visual_info) {
+ EPHYR_LOG_ERROR ("argh, could not find a remote visual with id:%d\n",
+ a_visual_id) ;
+ goto out ;
+ }
+ memset (&attrs, 0, sizeof (attrs)) ;
+ attrs.colormap = XCreateColormap (dpy,
+ RootWindow (dpy,
+ visual_info->screen),
+ visual_info->visual,
+ AllocNone) ;
+ winmask = CWColormap;
+
+ win = XCreateWindow (dpy, hostx_get_window (a_screen_number),
+ a_geometry->x, a_geometry->y,
+ a_geometry->width, a_geometry->height, 0,
+ visual_info->depth, InputOutput,
+ visual_info->visual, winmask, &attrs) ;
+ if (win == None) {
+ EPHYR_LOG_ERROR ("failed to create peer window\n") ;
+ goto out ;
+ }
+ XFlush (dpy) ;
+ XMapWindow (dpy, win) ;
+ *a_host_peer = win ;
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+int
+hostx_destroy_window (int a_win)
+{
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+ XDestroyWindow (dpy, a_win) ;
+ XFlush (dpy) ;
+ return TRUE ;
+}
+
+int
+hostx_set_window_geometry (int a_win, EphyrBox *a_geo)
+{
+ Display *dpy=hostx_get_display ();
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geo, FALSE) ;
+
+ EPHYR_LOG ("enter. x,y,w,h:(%d,%d,%d,%d)\n",
+ a_geo->x, a_geo->y,
+ a_geo->width, a_geo->height) ;
+
+ XMoveWindow (dpy, a_win, a_geo->x, a_geo->y) ;
+ XResizeWindow (dpy, a_win, a_geo->width, a_geo->height) ;
+ EPHYR_LOG ("leave\n") ;
+ return TRUE;
+}
+
+int
+hostx_set_window_bounding_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+ int i=0 ;
+ XRectangle *rects=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
+
+ EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
+
+ rects = calloc (a_num_rects, sizeof (XRectangle)) ;
+ for (i=0; i<a_num_rects; i++) {
+ rects[i].x = a_rects[i].x1 ;
+ rects[i].y = a_rects[i].y1 ;
+ rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
+ rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
+ EPHYR_LOG ("borders clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height) ;
+ }
+ /*this aways returns 1*/
+ XShapeCombineRectangles (dpy, a_window, ShapeBounding, 0, 0,
+ rects, a_num_rects, ShapeSet, YXBanded) ;
+ is_ok = TRUE ;
+
+ if (rects) {
+ free (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+int
+hostx_set_window_clipping_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+ int i=0 ;
+ XRectangle *rects=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
+
+ EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
+
+ rects = calloc (a_num_rects, sizeof (XRectangle)) ;
+ for (i=0; i<a_num_rects; i++) {
+ rects[i].x = a_rects[i].x1 ;
+ rects[i].y = a_rects[i].y1 ;
+ rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
+ rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
+ EPHYR_LOG ("clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height) ;
+ }
+ /*this aways returns 1*/
+ XShapeCombineRectangles (dpy, a_window, ShapeClip, 0, 0,
+ rects, a_num_rects, ShapeSet, YXBanded) ;
+ is_ok = TRUE ;
+
+ if (rects) {
+ free (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+int
+hostx_has_xshape (void)
+{
+ int event_base=0, error_base=0 ;
+ Display *dpy=hostx_get_display () ;
+ if (!XShapeQueryExtension (dpy,
+ &event_base,
+ &error_base)) {
+ return FALSE ;
+ }
+ return TRUE;
+}
+
+#ifdef XEPHYR_DRI
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id)
+{
+ int i=0 ;
+ ResourcePair *peer=NULL ;
+ Display *dpy=hostx_get_display ();
+
+ /*
+ * first make sure a resource peer
+ * does not exist already for
+ * a_local_resource_id
+ */
+ for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+ if (resource_peers[i].is_valid
+ && resource_peers[i].local_id == a_local_resource_id) {
+ peer = &resource_peers[i] ;
+ break ;
+ }
+ }
+ /*
+ * find one free peer entry, an feed it with
+ */
+ if (!peer) {
+ for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+ if (!resource_peers[i].is_valid) {
+ peer = &resource_peers[i] ;
+ break ;
+ }
+ }
+ if (peer) {
+ peer->remote_id = XAllocID (dpy);
+ peer->local_id = a_local_resource_id ;
+ peer->is_valid = TRUE ;
+ }
+ }
+ if (peer) {
+ *a_remote_resource_id = peer->remote_id ;
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id)
+{
+ int i=0 ;
+ ResourcePair *peer=NULL ;
+ for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+ if (resource_peers[i].is_valid
+ && resource_peers[i].local_id == a_local_resource_id) {
+ peer = &resource_peers[i] ;
+ break ;
+ }
+ }
+ if (peer) {
+ *a_remote_resource_id = peer->remote_id ;
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+int
+hostx_has_dri (void)
+{
+ int event_base=0, error_base=0 ;
+ Display *dpy=hostx_get_display () ;
+
+ if (!dpy)
+ return FALSE ;
+
+ if (!XF86DRIQueryExtension (dpy,
+ &event_base,
+ &error_base)) {
+ return FALSE ;
+ }
+ return TRUE ;
+}
+
+int
+hostx_has_glx (void)
+{
+ Display *dpy=hostx_get_display () ;
+ int event_base=0, error_base=0 ;
+
+ if (!glXQueryExtension (dpy, &event_base, &error_base)) {
+ return FALSE ;
+ }
+ return TRUE ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 4d5f37f0a..3caa466a7 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -40,8 +40,8 @@
typedef struct EphyrHostXVars EphyrHostXVars;
typedef struct EphyrHostXEvent EphyrHostXEvent;
-
-typedef enum EphyrHostXEventType
+typedef void* EphyrScreenInfo ;
+typedef enum EphyrHostXEventType
{
EPHYR_EV_MOUSE_MOTION,
EPHYR_EV_MOUSE_PRESS,
@@ -68,6 +68,7 @@ struct EphyrHostXEvent
struct mouse_motion {
int x;
int y;
+ int screen;
} mouse_motion;
struct mouse_down {
@@ -91,8 +92,34 @@ struct EphyrHostXEvent
int key_state;
};
+typedef struct {
+ VisualID visualid;
+ int screen;
+ int depth;
+ int class;
+ unsigned long red_mask;
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ int colormap_size;
+ int bits_per_rgb;
+} EphyrHostVisualInfo;
+
+typedef struct {
+ int x, y;
+ int width, height ;
+ int visualid ;
+} EphyrHostWindowAttributes;
+
+typedef struct {
+ int x,y,width,height;
+} EphyrBox;
+
+typedef struct {
+ short x1,y1,x2,y2;
+} EphyrRect;
+
int
-hostx_want_screen_size(int *width, int *height);
+hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
int
hostx_want_host_cursor(void);
@@ -107,7 +134,7 @@ int
hostx_want_fullscreen(void);
int
-hostx_want_preexisting_window(void);
+hostx_want_preexisting_window(EphyrScreenInfo screen);
void
hostx_use_preexisting_window(unsigned long win_id);
@@ -119,25 +146,32 @@ int
hostx_init(void);
void
+hostx_add_screen(EphyrScreenInfo screen, unsigned long win_id, int screen_num);
+
+void
hostx_set_display_name(char *name);
void
-hostx_set_win_title(char *extra_text);
+hostx_set_screen_number(EphyrScreenInfo screen, int number);
+
+void
+hostx_set_win_title(EphyrScreenInfo screen, char *extra_text);
int
hostx_get_depth (void);
int
-hostx_get_server_depth (void);
+hostx_get_server_depth (EphyrScreenInfo screen);
void
-hostx_set_server_depth(int depth);
+hostx_set_server_depth(EphyrScreenInfo screen, int depth);
int
-hostx_get_bpp(void);
+hostx_get_bpp(void *info);
void
-hostx_get_visual_masks (CARD32 *rmsk,
+hostx_get_visual_masks (void *info,
+ CARD32 *rmsk,
CARD32 *gmsk,
CARD32 *bmsk);
void
@@ -147,20 +181,72 @@ hostx_set_cmap_entry(unsigned char idx,
unsigned char b);
void*
-hostx_screen_init (int width, int height, int buffer_height);
+hostx_screen_init (EphyrScreenInfo screen,
+ int width, int height,
+ int buffer_height);
void
-hostx_paint_rect(int sx, int sy,
- int dx, int dy,
+hostx_paint_rect(EphyrScreenInfo screen,
+ int sx, int sy,
+ int dx, int dy,
int width, int height);
-void
-hostx_paint_debug_rect(int x, int y,
- int width, int height);
+
void
-hostx_load_keymap(void);
+hostx_load_keymap (void);
int
-hostx_get_event(EphyrHostXEvent *ev);
+hostx_get_event (EphyrHostXEvent *ev);
-#endif
+void*
+hostx_get_display (void) ;
+
+int
+hostx_get_window (int a_screen_number) ;
+
+int
+hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attr) ;
+
+int
+hostx_get_extension_info (const char *a_ext_name,
+ int *a_major_opcode,
+ int *a_first_even,
+ int *a_first_error) ;
+int
+hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
+ int *a_num_entries) ;
+
+int hostx_create_window (int a_screen_number,
+ EphyrBox *a_geometry,
+ int a_visual_id,
+ int *a_host_win /*out parameter*/) ;
+
+int hostx_destroy_window (int a_win) ;
+
+int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ;
+
+
+int hostx_set_window_bounding_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects) ;
+
+int hostx_set_window_clipping_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects) ;
+int hostx_has_xshape (void) ;
+
+#ifdef XEPHYR_DRI
+int hostx_lookup_peer_window (void *a_local_window,
+ int *a_host_peer /*out parameter*/) ;
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id) ;
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id) ;
+int hostx_has_dri (void) ;
+
+int hostx_has_glx (void) ;
+#endif /*XEPHYR_DRI*/
+
+#endif /*_XLIBS_STUFF_H_*/
diff --git a/hw/kdrive/ephyr/os.c b/hw/kdrive/ephyr/os.c
index 1a42495f3..4bf6e8858 100644
--- a/hw/kdrive/ephyr/os.c
+++ b/hw/kdrive/ephyr/os.c
@@ -28,9 +28,19 @@
#endif
#include "ephyr.h"
+extern void processScreenArg (char *screen_size, char *parent_id) ;
+
static int
EphyrInit (void)
{
+ /*
+ * make sure at least one screen
+ * has been added to the system.
+ */
+ if (!KdCardInfoLast ())
+ {
+ processScreenArg ("640x480", NULL) ;
+ }
return hostx_init();
}
diff --git a/hw/kdrive/fbdev/Makefile.am b/hw/kdrive/fbdev/Makefile.am
index 1ce4833a7..420855b8d 100644
--- a/hw/kdrive/fbdev/Makefile.am
+++ b/hw/kdrive/fbdev/Makefile.am
@@ -20,7 +20,7 @@ Xfbdev_LDADD = \
Xfbdev_DEPENDENCIES = \
libfbdev.a \
- @KDRIVE_LOCAL_LIBS@
+ $(KDRIVE_PURE_LIBS)
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am
index 20fae554a..07ab8c859 100644
--- a/hw/kdrive/src/Makefile.am
+++ b/hw/kdrive/src/Makefile.am
@@ -37,4 +37,4 @@ libkdrive_a_SOURCES = \
$(top_srcdir)/mi/miinitext.c
libkdrivestubs_a_SOURCES = \
- $(top_srcdir)/fb/fbcmap.c
+ $(top_srcdir)/fb/fbcmap_mi.c
diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 4bdf1ceb8..a6bfc0190 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -39,6 +39,7 @@
#include "xf86Config.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
+#include "dirent.h"
/* Sections for the default built-in configuration. */
@@ -174,7 +175,7 @@ videoPtrToDriverName(struct pci_device *dev)
case 0x8086:
if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800))
return "i740";
- else return "i810";
+ else return "intel";
case 0x102b: return "mga";
case 0x10c8: return "neomagic";
case 0x105d: return "i128";
@@ -214,27 +215,10 @@ xf86AutoConfig(void)
{
const char **p;
char buf[1024];
- struct pci_device_iterator *iter;
- struct pci_device * info = NULL;
const char *driver = NULL;
ConfigStatus ret;
- /* Find the primary device, and get some information about it. */
- iter = pci_slot_match_iterator_create(NULL);
- while ((info = pci_device_next(iter)) != NULL) {
- if (xf86IsPrimaryPci(info)) {
- break;
- }
- }
-
- pci_iterator_destroy(iter);
-
- if (!info) {
- ErrorF("Primary device is not PCI\n");
- }
-
- if (info)
- driver = videoPtrToDriverName(info);
+ driver = chooseVideoDriver();
AppendToConfig(BUILTIN_MODULE_SECTION);
AppendToConfig(BUILTIN_MONITOR_SECTION);
@@ -287,3 +271,212 @@ xf86AutoConfig(void)
return (ret == CONFIG_OK);
}
+
+int
+xchomp(char *line)
+{
+ size_t len = 0;
+
+ if (!line) {
+ return 1;
+ }
+
+ len = strlen(line);
+ if (line[len - 1] == '\n' && len > 0) {
+ line[len - 1] = '\0';
+ }
+ return 0;
+}
+
+GDevPtr
+autoConfigDevice(GDevPtr preconf_device)
+{
+ GDevPtr ptr = NULL;
+
+ if (!xf86configptr) {
+ return NULL;
+ }
+
+ /* If there's a configured section with no driver chosen, use it */
+ if (preconf_device) {
+ ptr = preconf_device;
+ } else {
+ ptr = (GDevPtr)xalloc(sizeof(GDevRec));
+ if (!ptr) {
+ return NULL;
+ }
+ memset((GDevPtr)ptr, 0, sizeof(GDevRec));
+ ptr->chipID = -1;
+ ptr->chipRev = -1;
+ ptr->irq = -1;
+
+ ptr->active = TRUE;
+ ptr->claimed = FALSE;
+ ptr->identifier = "Autoconfigured Video Device";
+ ptr->driver = NULL;
+ }
+ if (!ptr->driver) {
+ ptr->driver = chooseVideoDriver();
+ }
+
+ /* TODO Handle multiple screen sections */
+ if (xf86ConfigLayout.screens && !xf86ConfigLayout.screens->screen->device) {
+ xf86ConfigLayout.screens->screen->device = ptr;
+ ptr->myScreenSection = xf86ConfigLayout.screens->screen;
+ }
+ xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
+
+ return ptr;
+}
+
+static void
+matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
+{
+ DIR *idsdir;
+ FILE *fp;
+ struct dirent *direntry;
+ char *line = NULL;
+ size_t len;
+ ssize_t read;
+ char path_name[256], vendor_str[5], chip_str[5];
+ uint16_t vendor, chip;
+ int i, j;
+ idsdir = opendir("/usr/share/xserver-xorg/pci");
+
+ if (idsdir) {
+ direntry = readdir(idsdir);
+ /* Read the directory */
+ while (direntry) {
+ if (direntry->d_name[0] == '.') {
+ direntry = readdir(idsdir);
+ continue;
+ }
+ len = strlen(direntry->d_name);
+ /* A tiny bit of sanity checking. We should probably do better */
+ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) {
+ /* We need the full path name to open the file */
+ strncpy(path_name, "/usr/share/xserver-xorg/pci/", 256);
+ strncat(path_name, direntry->d_name, (256 - strlen(path_name)));
+ fp = fopen(path_name, "r");
+ if (fp == NULL) {
+ xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name);
+ goto end;
+ }
+ /* Read the file */
+ while ((read = getline(&line, &len, fp)) != -1) {
+ xchomp(line);
+ if (isdigit(line[0])) {
+ strncpy(vendor_str, line, 4);
+ vendor_str[4] = '\0';
+ vendor = (int)strtol(vendor_str, NULL, 16);
+ if ((strlen(&line[4])) == 0) {
+ chip_str[0] = '\0';
+ chip = -1;
+ } else {
+ /* Handle trailing whitespace */
+ if (isspace(line[4])) {
+ chip_str[0] = '\0';
+ chip = -1;
+ } else {
+ /* Ok, it's a real ID */
+ strncpy(chip_str, &line[4], 4);
+ chip_str[4] = '\0';
+ chip = (int)strtol(chip_str, NULL, 16);
+ }
+ }
+ if (vendor == match_vendor && chip == match_chip ) {
+ i = 0;
+ while (matches[i]) {
+ i++;
+ }
+ matches[i] = (char*)xalloc(sizeof(char) * strlen(direntry->d_name) - 3);
+ if (!matches[i]) {
+ xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n");
+ goto end;
+ }
+ /* hack off the .ids suffix. This should guard
+ * against other problems, but it will end up
+ * taking off anything after the first '.' */
+ for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) {
+ if (direntry->d_name[j] == '.') {
+ matches[i][j] = '\0';
+ break;
+ } else {
+ matches[i][j] = direntry->d_name[j];
+ }
+ }
+ xf86Msg(X_INFO, "Matched %s from file name %s in autoconfig\n", matches[i], direntry->d_name);
+
+ }
+ } else {
+ /* TODO Handle driver overrides here */
+ }
+ }
+ fclose(fp);
+ }
+ direntry = readdir(idsdir);
+ }
+ }
+ end:
+ xfree(line);
+ closedir(idsdir);
+}
+
+char*
+chooseVideoDriver(void)
+{
+ struct pci_device * info = NULL;
+ struct pci_device_iterator *iter;
+ char *chosen_driver = NULL;
+ int i;
+ char *matches[20]; /* If we have more than 20 drivers we're in trouble */
+
+ for (i=0 ; i<20 ; i++)
+ matches[i] = NULL;
+
+ /* Find the primary device, and get some information about it. */
+ iter = pci_slot_match_iterator_create(NULL);
+ while ((info = pci_device_next(iter)) != NULL) {
+ if (xf86IsPrimaryPci(info)) {
+ break;
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+ if (!info) {
+ ErrorF("Primary device is not PCI\n");
+ }
+
+ matchDriverFromFiles(matches, info->vendor_id, info->device_id);
+
+ /* TODO Handle multiple drivers claiming to support the same PCI ID */
+ if (matches[0]) {
+ chosen_driver = matches[0];
+ } else {
+ chosen_driver = videoPtrToDriverName(info);
+ #if 0 /* Save for later */
+ #if defined __i386__ || defined __amd64__ || defined __hurd__
+ chosen_driver = "vesa";
+ #elif defined __alpha__
+ chosen_driver = "vga";
+ #elif defined __sparc__
+ chosen_driver = "sunffb";
+ #else
+ chosen_driver = "fbdev";
+ #endif
+ #endif
+ }
+
+ xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);
+
+ i = 0;
+ while (matches[i]) {
+ if (matches[i] != chosen_driver) {
+ xfree(matches[i]);
+ }
+ i++;
+ }
+
+ return chosen_driver;
+}
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 71e008069..96fadc9dd 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -77,7 +77,7 @@ extern DeviceAssocRec mouse_assoc;
#include "picture.h"
#endif
-#if (defined(i386) || defined(__i386__)) && \
+#if (defined(__i386__)) && \
(defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
defined(__NetBSD__) || defined(linux) || \
(defined(SVR4) && !defined(sun)) || defined(__GNU__))
@@ -877,7 +877,7 @@ static OptionInfoRec FlagOptions[] = {
{0}, FALSE },
};
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
static Bool
detectPC98(void)
{
@@ -1164,7 +1164,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
xf86Info.pixmap24 = Pix24DontCare;
xf86Info.pix24From = X_DEFAULT;
}
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
xf86Info.pc98 = value;
if (value) {
@@ -1813,11 +1813,6 @@ configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen)
if (!servlayoutp)
return FALSE;
- if (conf_screen == NULL) {
- xf86ConfigError("No Screen sections present\n");
- return FALSE;
- }
-
/*
* which screen section is the active one?
*
@@ -1905,6 +1900,12 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
XF86ConfAdaptorLinkPtr conf_adaptor;
Bool defaultMonitor = FALSE;
+ if (!conf_screen) {
+ conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec));
+ conf_screen->scrn_identifier = "Default Screen Section";
+ xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
+ }
+
xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
scrnum);
/*
@@ -1939,9 +1940,20 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
return FALSE;
}
+ /* Configure the device. If there isn't one configured, attach to the
+ * first inactive one that we can configure. If there's none that work,
+ * set it to NULL so that the section can be autoconfigured later */
screenp->device = xnfcalloc(1, sizeof(GDevRec));
- configDevice(screenp->device,conf_screen->scrn_device, TRUE);
- screenp->device->myScreenSection = screenp;
+ if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
+ conf_screen->scrn_device = xf86configptr->conf_device_lst;
+ xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
+ "\tUsing the first device section listed.\n", screenp->id);
+ }
+ if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
+ screenp->device->myScreenSection = screenp;
+ } else {
+ screenp->device = NULL;
+ }
screenp->options = conf_screen->scrn_option_lst;
/*
@@ -2230,13 +2242,17 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
{
int i;
+ if (!conf_device) {
+ return FALSE;
+ }
+
if (active)
xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
conf_device->dev_identifier);
else
xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
conf_device->dev_identifier);
-
+
devicep->identifier = conf_device->dev_identifier;
devicep->vendor = conf_device->dev_vendor;
devicep->board = conf_device->dev_board;
diff --git a/hw/xfree86/common/xf86Config.h b/hw/xfree86/common/xf86Config.h
index b8b5fd42a..a174e463b 100644
--- a/hw/xfree86/common/xf86Config.h
+++ b/hw/xfree86/common/xf86Config.h
@@ -34,6 +34,8 @@
#define _xf86_config_h
#include "xf86Optrec.h"
+#include "xf86Parser.h"
+#include "xf86str.h"
#ifdef HAVE_PARSER_DECLS
/*
@@ -65,5 +67,8 @@ Bool xf86BuiltinInputDriver(const char *);
ConfigStatus xf86HandleConfigFile(Bool);
Bool xf86AutoConfig(void);
+GDevPtr autoConfigDevice(GDevPtr preconf_device);
+char* chooseVideoDriver(void);
+int xchomp(char *line);
#endif /* _xf86_config_h */
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index c31879ca3..574602f43 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -317,7 +317,7 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
}
break;
#if !defined(__SOL8__) && !defined(sgi) && \
- (!defined(sun) || defined(i386)) && defined(VT_ACTIVATE)
+ (!defined(sun) || defined(__i386__)) && defined(VT_ACTIVATE)
case ACTION_SWITCHSCREEN:
if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) {
int vtno = *((int *) arg);
@@ -340,7 +340,7 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
#else
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno + 1) < 0)
#endif
-#if defined (__SCO__) || (defined(sun) && defined (i386) && defined (SVR4)) || defined(__UNIXWARE__)
+#if defined (__SCO__) || (defined(sun) && defined (__i386__) && defined (SVR4)) || defined(__UNIXWARE__)
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 0) < 0)
#else
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) < 0)
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 4b5105632..d796d627c 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -126,7 +126,7 @@ xf86InfoRec xf86Info = {
PCIOsConfig, /* pciFlags */
Pix24DontCare, /* pixmap24 */
X_DEFAULT, /* pix24From */
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
FALSE, /* pc98 */
#endif
TRUE, /* pmFlag */
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index b6fc6b629..1ef79730c 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -2341,7 +2341,7 @@ xf86GetAllowMouseOpenFail()
_X_EXPORT Bool
xf86IsPc98()
{
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
return xf86Info.pc98;
#else
return FALSE;
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 9ff2da73a..b3cae2707 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -563,6 +563,16 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
}
/* Load all driver modules specified in the config file */
+ /* If there aren't any specified in the config file, autoconfig them */
+ /* FIXME: Does not handle multiple active screen sections, but I'm not
+ * sure if we really want to handle that case*/
+ GDevPtr configured_device = xf86ConfigLayout.screens->screen->device;
+ if ((!configured_device) || (!configured_device->driver)) {
+ if (!autoConfigDevice(configured_device)) {
+ xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
+ return ;
+ }
+ }
if ((modulelist = xf86DriverlistFromConfig())) {
xf86LoadModules(modulelist, NULL);
xfree(modulelist);
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 09ebb0717..75d497471 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -109,7 +109,7 @@ typedef struct {
PciProbeType pciFlags;
Pix24Flags pixmap24;
MessageType pix24From;
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
Bool pc98;
#endif
Bool pmFlag;
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 0365ddd62..af98b4fd5 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -142,6 +142,7 @@ typedef enum {
# define M_T_DEFAULT 0x10 /* (VESA) default modes */
# define M_T_USERDEF 0x20 /* One of the modes from the config file */
# define M_T_DRIVER 0x40 /* Supplied by the driver (EDID, etc) */
+# define M_T_USERPREF 0x80 /* mode preferred by the user config */
/* Video mode */
typedef struct _DisplayModeRec {
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 84c0508bc..c35386354 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -953,7 +953,7 @@ static Bool
DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- __GLXscreen *pGLXScreen = __glXgetActiveScreen(pScreen->myNum);
+ __GLXscreen *pGLXScreen = glxGetScreen(pScreen);
__GLcontextModes *modes = pGLXScreen->modes;
void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
DRIContextPrivPtr pDRIContextPriv;
@@ -1017,7 +1017,7 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
XID context, drm_context_t * pHWContext)
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- __GLXscreen *pGLXScreen = __glXgetActiveScreen(pScreen->myNum);
+ __GLXscreen *pGLXScreen = glxGetScreen(pScreen);
__GLcontextModes *modes = pGLXScreen->modes;
void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
DRIContextPrivPtr pDRIContextPriv;
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 064ff1689..0a48d5bd3 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -711,7 +711,8 @@ xf86DefaultMode (xf86OutputPtr output, int width, int height)
for (mode = output->probed_modes; mode; mode = mode->next)
{
int dpi;
- int preferred = (mode->type & M_T_PREFERRED) != 0;
+ int preferred = (((mode->type & M_T_PREFERRED) != 0) +
+ ((mode->type & M_T_USERPREF) != 0));
int diff;
if (xf86ModeWidth (mode, output->initial_rotation) > width ||
@@ -1415,7 +1416,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
mode->prev = NULL;
output->probed_modes = mode;
}
- mode->type |= M_T_PREFERRED;
+ mode->type |= (M_T_PREFERRED|M_T_USERPREF);
}
else
mode->type &= ~M_T_PREFERRED;
@@ -1532,6 +1533,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o, c;
DisplayModePtr target_mode = NULL;
+ int target_preferred = 0;
Rotation target_rotation = RR_Rotate_0;
xf86CrtcPtr *crtcs;
DisplayModePtr *modes;
@@ -1572,43 +1574,34 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
}
/*
- * Let outputs with preferred modes drive screen size
+ * User preferred > preferred > other modes
*/
for (o = 0; o < config->num_output; o++)
{
- xf86OutputPtr output = config->output[o];
+ xf86OutputPtr output = config->output[o];
+ DisplayModePtr default_mode;
+ int default_preferred;
- if (enabled[o] &&
- xf86OutputHasPreferredMode (output, width, height))
+ if (!enabled[o])
+ continue;
+ default_mode = xf86DefaultMode (output, width, height);
+ if (!default_mode)
+ continue;
+ default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) +
+ ((default_mode->type & M_T_USERPREF) != 0));
+ if (default_preferred > target_preferred || !target_mode)
{
- target_mode = xf86DefaultMode (output, width, height);
+ target_mode = default_mode;
+ target_preferred = default_preferred;
target_rotation = output->initial_rotation;
- if (target_mode)
- {
- modes[o] = target_mode;
- config->compat_output = o;
- break;
- }
- }
- }
- if (!target_mode)
- {
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- if (enabled[o])
- {
- target_mode = xf86DefaultMode (output, width, height);
- target_rotation = output->initial_rotation;
- if (target_mode)
- {
- modes[o] = target_mode;
- config->compat_output = o;
- break;
- }
- }
+ config->compat_output = o;
}
}
+ if (target_mode)
+ modes[config->compat_output] = target_mode;
+ /*
+ * Fill in other output modes
+ */
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
@@ -2134,8 +2127,12 @@ _X_EXPORT xf86MonPtr
xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
{
ScrnInfoPtr scrn = output->scrn;
+ xf86MonPtr mon;
+
+ mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
+ xf86DDCApplyQuirks (scrn->scrnIndex, pDDCBus);
- return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
+ return mon;
}
static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D",
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 9693e12bb..4c843cd83 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -39,6 +39,9 @@
#ifndef M_T_DRIVER
#define M_T_DRIVER 0x40
#endif
+#ifndef M_T_USERPREF
+#define M_T_USERPREF 0x80
+#endif
#ifndef HARDWARE_CURSOR_ARGB
#define HARDWARE_CURSOR_ARGB 0x00004000
#endif
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 8b5e69d9a..9fa5fef9e 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -54,6 +54,16 @@ typedef enum {
DDC_QUIRK_PREFER_LARGE_60 = 1 << 0,
/* 135MHz clock is too high, drop a bit */
DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1,
+ /* Prefer the largest mode at 75 Hz */
+ DDC_QUIRK_PREFER_LARGE_75 = 1 << 2,
+ /* Convert detailed timing's horizontal from units of cm to mm */
+ DDC_QUIRK_DETAILED_H_IN_CM = 1 << 3,
+ /* Convert detailed timing's vertical from units of cm to mm */
+ DDC_QUIRK_DETAILED_V_IN_CM = 1 << 4,
+ /* Detailed timing descriptors have bogus size values, so just take the
+ * maximum size and use that.
+ */
+ DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5,
} ddc_quirk_t;
static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@@ -81,6 +91,52 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
return FALSE;
}
+static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #11603: Funai Electronics PM36B */
+ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+ DDC->vendor.prod_id == 13600)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #10304: "LGPhilipsLCD LP154W01-A5" */
+ /* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */
+ if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
+ DDC->vendor.prod_id == 0)
+ return TRUE;
+
+ /* Bug #11603: Funai Electronics PM36B */
+ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+ DDC->vendor.prod_id == 13600)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #11603: Funai Electronics PM36B */
+ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+ DDC->vendor.prod_id == 13600)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #10304: LGPhilipsLCD LP154W01-A5 */
+ if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
+ DDC->vendor.prod_id == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
{
/* Envision Peripherals, Inc. EN-7100e. See bug #9550. */
@@ -106,6 +162,22 @@ static const ddc_quirk_map_t ddc_quirks[] = {
quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH,
"Recommended 135MHz pixel clock is too high"
},
+ {
+ quirk_prefer_large_75, DDC_QUIRK_PREFER_LARGE_75,
+ "Detailed timing is not preferred, use largest mode at 75Hz"
+ },
+ {
+ quirk_detailed_h_in_cm, DDC_QUIRK_DETAILED_H_IN_CM,
+ "Detailed timings give horizontal size in cm."
+ },
+ {
+ quirk_detailed_v_in_cm, DDC_QUIRK_DETAILED_V_IN_CM,
+ "Detailed timings give vertical size in cm."
+ },
+ {
+ quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
+ "Detailed timings give sizes in cm."
+ },
{
NULL, DDC_QUIRK_NONE,
"No known quirks"
@@ -303,6 +375,98 @@ DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
}
}
+static ddc_quirk_t
+xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose)
+{
+ ddc_quirk_t quirks;
+ int i;
+
+ quirks = DDC_QUIRK_NONE;
+ for (i = 0; ddc_quirks[i].detect; i++) {
+ if (ddc_quirks[i].detect (scrnIndex, DDC)) {
+ if (verbose) {
+ xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
+ ddc_quirks[i].description);
+ }
+ quirks |= ddc_quirks[i].quirk;
+ }
+ }
+
+ return quirks;
+}
+
+/**
+ * Applies monitor-specific quirks to the decoded EDID information.
+ *
+ * Note that some quirks applying to the mode list are still implemented in
+ * xf86DDCGetModes.
+ */
+void
+xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC)
+{
+ ddc_quirk_t quirks = xf86DDCDetectQuirks (scrnIndex, DDC, FALSE);
+ int i;
+
+ for (i = 0; i < DET_TIMINGS; i++) {
+ struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
+
+ if (det_mon->type != DT)
+ continue;
+
+ if (quirks & DDC_QUIRK_DETAILED_H_IN_CM)
+ det_mon->section.d_timings.h_size *= 10;
+
+ if (quirks & DDC_QUIRK_DETAILED_V_IN_CM)
+ det_mon->section.d_timings.v_size *= 10;
+
+ if (quirks & DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
+ det_mon->section.d_timings.h_size = 10 * DDC->features.hsize;
+ det_mon->section.d_timings.v_size = 10 * DDC->features.vsize;
+ }
+ }
+}
+
+/**
+ * Walks the modes list, finding the mode with the largest area which is
+ * closest to the target refresh rate, and marks it as the only preferred mode.
+*/
+static void
+xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
+ float target_refresh)
+{
+ DisplayModePtr mode, best = modes;
+
+ for (mode = modes; mode; mode = mode->next)
+ {
+ mode->type &= ~M_T_PREFERRED;
+
+ if (mode == best) continue;
+
+ if (mode->HDisplay * mode->VDisplay >
+ best->HDisplay * best->VDisplay)
+ {
+ best = mode;
+ continue;
+ }
+ if (mode->HDisplay * mode->VDisplay ==
+ best->HDisplay * best->VDisplay)
+ {
+ double mode_refresh = xf86ModeVRefresh (mode);
+ double best_refresh = xf86ModeVRefresh (best);
+ double mode_dist = fabs(mode_refresh - target_refresh);
+ double best_dist = fabs(best_refresh - target_refresh);
+
+ if (mode_dist < best_dist)
+ {
+ best = mode;
+ continue;
+ }
+ }
+ }
+ if (best)
+ best->type |= M_T_PREFERRED;
+}
+
_X_EXPORT DisplayModePtr
xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
{
@@ -312,15 +476,9 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
DDC->vendor.name, DDC->vendor.prod_id);
- quirks = DDC_QUIRK_NONE;
- for (i = 0; ddc_quirks[i].detect; i++)
- if (ddc_quirks[i].detect (scrnIndex, DDC))
- {
- xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
- ddc_quirks[i].description);
- quirks |= ddc_quirks[i].quirk;
- }
-
+
+ quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
+
preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
preferred = 0;
@@ -357,32 +515,11 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
Modes = xf86ModesAdd(Modes, Mode);
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
- {
- DisplayModePtr best = Modes;
- for (Mode = Modes; Mode; Mode = Mode->next)
- {
- if (Mode == best) continue;
- if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
- {
- best = Mode;
- continue;
- }
- if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
- {
- double mode_refresh = xf86ModeVRefresh (Mode);
- double best_refresh = xf86ModeVRefresh (best);
- double mode_dist = fabs(mode_refresh - 60.0);
- double best_dist = fabs(best_refresh - 60.0);
- if (mode_dist < best_dist)
- {
- best = Mode;
- continue;
- }
- }
- }
- if (best)
- best->type |= M_T_PREFERRED;
- }
+ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60);
+
+ if (quirks & DDC_QUIRK_PREFER_LARGE_75)
+ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75);
+
return Modes;
}
diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c
index f49c2921c..99817898a 100644
--- a/hw/xfree86/modes/xf86Modes.c
+++ b/hw/xfree86/modes/xf86Modes.c
@@ -389,8 +389,8 @@ xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
bad = TRUE;
for (i = 0; i < mon->nHsync; i++) {
- if (xf86ModeHSync(mode) >= mon->hsync[i].lo &&
- xf86ModeHSync(mode) <= mon->hsync[i].hi)
+ if (xf86ModeHSync(mode) >= mon->hsync[i].lo * (1-SYNC_TOLERANCE) &&
+ xf86ModeHSync(mode) <= mon->hsync[i].hi * (1+SYNC_TOLERANCE))
{
bad = FALSE;
}
@@ -400,8 +400,8 @@ xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
bad = TRUE;
for (i = 0; i < mon->nVrefresh; i++) {
- if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo &&
- xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi)
+ if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo * (1-SYNC_TOLERANCE) &&
+ xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi * (1+SYNC_TOLERANCE))
{
bad = FALSE;
}
@@ -434,7 +434,8 @@ xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
for (mode = modeList; mode != NULL; mode = mode->next) {
Bool good = FALSE;
for (i = 0; i < n_ranges; i++) {
- if (mode->Clock >= min[i] && mode->Clock <= max[i]) {
+ if (mode->Clock >= min[i] * (1-SYNC_TOLERANCE) &&
+ mode->Clock <= max[i] * (1+SYNC_TOLERANCE)) {
good = TRUE;
break;
}
diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h
index 2bd4edeba..3722d25a0 100644
--- a/hw/xfree86/modes/xf86Modes.h
+++ b/hw/xfree86/modes/xf86Modes.h
@@ -95,4 +95,7 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
DisplayModePtr
xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
+void
+xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC);
+
#endif /* _XF86MODES_H_ */
diff --git a/hw/xfree86/os-support/assyntax.h b/hw/xfree86/os-support/assyntax.h
index 718312cf0..d3e96e5fd 100644
--- a/hw/xfree86/os-support/assyntax.h
+++ b/hw/xfree86/os-support/assyntax.h
@@ -91,7 +91,7 @@
#define GNU_ASSEMBLER
#endif
-#if (defined(__STDC__) && !defined(UNIXCPP)) || (defined (sun) && defined (i386) && defined (SVR4) && defined (__STDC__) && !defined (__GNUC__))
+#if (defined(__STDC__) && !defined(UNIXCPP)) || (defined (sun) && defined (__i386__) && defined (SVR4) && defined (__STDC__) && !defined (__GNUC__))
#define CONCAT(x, y) x ## y
#else
#define CONCAT(x, y) x/**/y
diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h
index bb93260d1..6bd0eb7fc 100644
--- a/hw/xfree86/os-support/bus/Pci.h
+++ b/hw/xfree86/os-support/bus/Pci.h
@@ -210,7 +210,7 @@
# define ARCH_PCI_INIT ia64linuxPciInit
# endif
# define XF86SCANPCI_WRAPPER ia64ScanPCIWrapper
-#elif defined(__i386__) || defined(i386)
+#elif defined(__i386__)
# if defined(linux)
# define ARCH_PCI_INIT linuxPciInit
# else
diff --git a/hw/xfree86/os-support/bus/ix86Pci.c b/hw/xfree86/os-support/bus/ix86Pci.c
index 3ed4f1422..e54246355 100644
--- a/hw/xfree86/os-support/bus/ix86Pci.c
+++ b/hw/xfree86/os-support/bus/ix86Pci.c
@@ -188,8 +188,8 @@ static pciBusFuncs_t ix86Funcs0 = {
/* pciReadLong */ ix86PciReadLongSetup,
/* pciWriteLong */ ix86PciWriteLongSetup,
/* pciSetBitsLong */ ix86PciSetBitsLongSetup,
-#endif
/* pciAddrHostToBus */ pciAddrNOOP,
+#endif
/* pciAddrBusToHost */ pciAddrNOOP
};
@@ -198,8 +198,8 @@ static pciBusFuncs_t ix86Funcs1 = {
/* pciReadLong */ ix86PciReadLongCFG1,
/* pciWriteLong */ ix86PciWriteLongCFG1,
/* pciSetBitsLong */ ix86PciSetBitsLongCFG1,
-#endif
/* pciAddrHostToBus */ pciAddrNOOP,
+#endif
/* pciAddrBusToHost */ pciAddrNOOP
};
@@ -208,8 +208,8 @@ static pciBusFuncs_t ix86Funcs2 = {
/* pciReadLong */ ix86PciReadLongCFG2,
/* pciWriteLong */ ix86PciWriteLongCFG2,
/* pciSetBitsLong */ ix86PciSetBitsLongCFG2,
-#endif
/* pciAddrHostToBus */ pciAddrNOOP,
+#endif
/* pciAddrBusToHost */ pciAddrNOOP
};
@@ -223,6 +223,20 @@ static pciBusInfo_t ix86Pci0 = {
/* bridge */ NULL
};
+_X_EXPORT pointer
+xf86MapDomainMemory(int ScreenNum, int Flags, struct pci_device *dev,
+ ADDRESS Base, unsigned long Size)
+{
+ return xf86MapVidMem(ScreenNum, Flags, Base, Size);
+}
+
+IOADDRESS
+xf86MapLegacyIO(struct pci_device *dev)
+{
+ (void)dev;
+ return 0;
+}
+
static Bool
ix86PciBusCheck(void)
{
diff --git a/hw/xfree86/os-support/shared/stdResource.c b/hw/xfree86/os-support/shared/stdResource.c
index 7229d55b5..c144211f0 100644
--- a/hw/xfree86/os-support/shared/stdResource.c
+++ b/hw/xfree86/os-support/shared/stdResource.c
@@ -44,7 +44,7 @@
#include "bus/Pci.h"
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
- defined(__DragonFly__)
+ defined(__DragonFly__) || defined(__sun)
#define xf86StdAccResFromOS xf86AccResFromOS
#endif
diff --git a/hw/xfree86/os-support/solaris/sun_bios.c b/hw/xfree86/os-support/solaris/sun_bios.c
index 6a132f5a3..1223dcd68 100644
--- a/hw/xfree86/os-support/solaris/sun_bios.c
+++ b/hw/xfree86/os-support/solaris/sun_bios.c
@@ -26,7 +26,7 @@
#include <xorg-config.h>
#endif
-#ifdef i386
+#ifdef __i386__
#define _NEED_SYSI86
#endif
#include "xf86.h"
@@ -66,7 +66,7 @@ xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
Offset += Base & (psize - 1);
Base &= ~(psize - 1);
mlen = (Offset + Len + psize - 1) & ~(psize - 1);
-#if defined(i386) && !defined(__SOL8__)
+#if defined(__i386__) && !defined(__SOL8__)
if (Base >= 0xA0000 && Base + mlen < 0xFFFFF && xf86Info.vtno >= 0)
sprintf(solx86_vtname, "/dev/vt%02d", xf86Info.vtno);
else
diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 08d35c59c..c7fac524f 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -29,7 +29,7 @@
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
-#if defined(__i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
# include <sys/kd.h>
#endif
@@ -40,7 +40,7 @@ static int VTnum = -1;
static int xf86StartVT = -1;
#endif
-#if defined(__SOL8__) || !defined(__i386)
+#if defined(__SOL8__) || !defined(__i386__)
static char fb_dev[PATH_MAX] = "/dev/fb";
#else
static char fb_dev[PATH_MAX] = "/dev/console";
@@ -209,11 +209,11 @@ xf86CloseConsole(void)
#ifdef HAS_USL_VTS
struct vt_mode VT;
#endif
-#if defined(__SOL8__) || !defined(i386)
+#if defined(__SOL8__) || !defined(__i386__)
int tmp;
#endif
-#if !defined(i386) && !defined(__x86)
+#if !defined(__i386__) && !defined(__x86)
if (!xf86DoProbe && !xf86DoConfigure) {
int fd;
@@ -332,7 +332,7 @@ xf86ProcessArgument(int argc, char **argv, int i)
#endif /* HAS_USL_VTS */
-#if defined(__SOL8__) || !defined(i386)
+#if defined(__SOL8__) || !defined(__i386__)
if ((i + 1) < argc) {
if (!strcmp(argv[i], "-dev")) {
@@ -352,7 +352,7 @@ void xf86UseMsg()
#ifdef HAS_USL_VTS
ErrorF("vtXX Use the specified VT number\n");
#endif
-#if defined(__SOL8__) || !defined(i386)
+#if defined(__SOL8__) || !defined(__i386__)
ErrorF("-dev <fb> Framebuffer device\n");
#endif
ErrorF("-keeptty Don't detach controlling tty\n");
diff --git a/hw/xfree86/os-support/solaris/sun_vid.c b/hw/xfree86/os-support/solaris/sun_vid.c
index 4f2ab871f..494b2cfbf 100644
--- a/hw/xfree86/os-support/solaris/sun_vid.c
+++ b/hw/xfree86/os-support/solaris/sun_vid.c
@@ -28,7 +28,7 @@
#include <sys/types.h> /* get __x86 definition if not set by compiler */
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
#define _NEED_SYSI86
#endif
#include "xf86.h"
@@ -108,7 +108,7 @@ xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
* TSI - 2001.09 - SPARC changes
*/
-#if defined(i386) && !defined(__SOL8__)
+#if defined(__i386__) && !defined(__SOL8__)
if(Base < 0xFFFFF)
sprintf(vtname, "/dev/vt%02d", xf86Info.vtno);
else
@@ -148,14 +148,14 @@ xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
/* I/O Permissions section */
/***************************************************************************/
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
static Bool ExtendedEnabled = FALSE;
#endif
_X_EXPORT Bool
xf86EnableIO(void)
{
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
if (ExtendedEnabled)
return TRUE;
@@ -171,7 +171,7 @@ xf86EnableIO(void)
_X_EXPORT void
xf86DisableIO(void)
{
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
if(!ExtendedEnabled)
return;
@@ -188,7 +188,7 @@ xf86DisableIO(void)
_X_EXPORT Bool xf86DisableInterrupts(void)
{
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0))
return FALSE;
@@ -207,7 +207,7 @@ _X_EXPORT Bool xf86DisableInterrupts(void)
_X_EXPORT void xf86EnableInterrupts(void)
{
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0))
return;
diff --git a/hw/xfree86/os-support/sysv/sysv_video.c b/hw/xfree86/os-support/sysv/sysv_video.c
index 5811947bd..9972bcaa4 100644
--- a/hw/xfree86/os-support/sysv/sysv_video.c
+++ b/hw/xfree86/os-support/sysv/sysv_video.c
@@ -234,7 +234,7 @@ unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
return;
}
-#if defined(SVR4) && defined(i386) && !defined(sun)
+#if defined(SVR4) && defined(__i386__) && !defined(sun)
/*
* For some SVR4 versions, a 32-bit read is done for the first location
* in each page when the page is first mapped. If this is done while
@@ -270,7 +270,7 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
pVidMem->linearSupported = linearVidMem();
pVidMem->mapMem = mapVidMem;
pVidMem->unmapMem = unmapVidMem;
-#if defined(SVR4) && defined(i386) && !defined(sun)
+#if defined(SVR4) && defined(__i386__) && !defined(sun)
pVidMem->readSideEffects = readSideEffects;
#endif
pVidMem->initialised = TRUE;
diff --git a/hw/xfree86/os-support/xf86_OSlib.h b/hw/xfree86/os-support/xf86_OSlib.h
index fcc79be38..662dbaace 100644
--- a/hw/xfree86/os-support/xf86_OSlib.h
+++ b/hw/xfree86/os-support/xf86_OSlib.h
@@ -100,7 +100,7 @@ typedef signed long xf86ssize_t;
/**************************************************************************/
#if (defined(SYSV) || defined(SVR4)) && \
!defined(DGUX) && !defined(sgi) && \
- (defined(sun) || defined(i386))
+ (defined(sun) || defined(__i386__))
# ifdef SCO325
# ifndef _SVID3
# define _SVID3
@@ -140,7 +140,7 @@ typedef signed long xf86ssize_t;
# endif /* SVR4 && !sun */
/* V86SC_IOPL was moved to <sys/sysi86.h> on Solaris 7 and later */
# if defined(sun) && defined (SVR4) /* Solaris? */
-# if defined(i386) || defined(__x86) /* on x86 or x64? */
+# if defined(__i386__) || defined(__x86) /* on x86 or x64? */
# if !defined(V86SC_IOPL) /* Solaris 7 or later? */
# include <sys/v86.h> /* Nope */
# endif
@@ -148,7 +148,7 @@ typedef signed long xf86ssize_t;
# else
# include <sys/v86.h> /* Not solaris */
# endif /* sun && i386 && SVR4 */
-# if defined(sun) && (defined (i386) || defined(__x86)) && defined (SVR4)
+# if defined(sun) && (defined (__i386__) || defined(__x86)) && defined (SVR4)
# include <sys/psw.h>
# endif
# endif /* _NEED_SYSI86 */
@@ -224,15 +224,11 @@ typedef signed long xf86ssize_t;
# define POSIX_TTY
# endif
-# if defined(sun) && defined (i386) && defined (SVR4) && !defined(__SOL8__)
+# if defined(sun) && defined (__i386__) && defined (SVR4) && !defined(__SOL8__)
# define USE_VT_SYSREQ
# define VT_SYSREQ_DEFAULT TRUE
# endif
-# if defined(ATT) && !defined(i386)
-# define i386 /* not defined in ANSI C mode */
-# endif /* ATT && !i386 */
-
# ifdef SYSV
# if !defined(ISC) || defined(ISC202) || defined(ISC22)
# define NEED_STRERROR
diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h
index c20c1958c..4d5fbcfab 100644
--- a/hw/xfree86/parser/Configint.h
+++ b/hw/xfree86/parser/Configint.h
@@ -186,8 +186,6 @@ else\
"The Inactive keyword must be followed by a Device name in quotes."
#define UNDEFINED_SCREEN_MSG \
"Undefined Screen \"%s\" referenced by ServerLayout \"%s\"."
-#define UNDEFINED_MONITOR_MSG \
-"Undefined Monitor \"%s\" referenced by Screen \"%s\"."
#define UNDEFINED_MODES_MSG \
"Undefined Modes Section \"%s\" referenced by Monitor \"%s\"."
#define UNDEFINED_DEVICE_MSG \
@@ -204,8 +202,6 @@ else\
"This section must have an Identifier line."
#define ONLY_ONE_MSG \
"This section must have only one of either %s line."
-#define UNDEFINED_DRIVER_MSG \
-"Device section \"%s\" must have a Driver line."
#define UNDEFINED_INPUTDRIVER_MSG \
"InputDevice section \"%s\" must have a Driver line."
#define INVALID_GAMMA_MSG \
diff --git a/hw/xfree86/parser/Device.c b/hw/xfree86/parser/Device.c
index 6ad5601b5..216789fc1 100644
--- a/hw/xfree86/parser/Device.c
+++ b/hw/xfree86/parser/Device.c
@@ -357,26 +357,6 @@ xf86freeDeviceList (XF86ConfDevicePtr ptr)
}
}
-int
-xf86validateDevice (XF86ConfigPtr p)
-{
- XF86ConfDevicePtr device = p->conf_device_lst;
-
- if (!device) {
- xf86validationError ("At least one Device section is required.");
- return (FALSE);
- }
-
- while (device) {
- if (!device->dev_driver) {
- xf86validationError (UNDEFINED_DRIVER_MSG, device->dev_identifier);
- return (FALSE);
- }
- device = device->list.next;
- }
- return (TRUE);
-}
-
XF86ConfDevicePtr
xf86findDevice (const char *ident, XF86ConfDevicePtr p)
{
diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c
index 79e1d24ef..4524f17f6 100644
--- a/hw/xfree86/parser/Screen.c
+++ b/hw/xfree86/parser/Screen.c
@@ -498,12 +498,6 @@ xf86validateScreen (XF86ConfigPtr p)
XF86ConfDevicePtr device;
XF86ConfAdaptorLinkPtr adaptor;
- if (!screen)
- {
- xf86validationError ("At least one Screen section is required.");
- return (FALSE);
- }
-
while (screen)
{
if (screen->scrn_obso_driver && !screen->scrn_identifier)
@@ -512,13 +506,7 @@ xf86validateScreen (XF86ConfigPtr p)
monitor = xf86findMonitor (screen->scrn_monitor_str, p->conf_monitor_lst);
if (screen->scrn_monitor_str)
{
- if (!monitor)
- {
- xf86validationError (UNDEFINED_MONITOR_MSG,
- screen->scrn_monitor_str, screen->scrn_identifier);
- return (FALSE);
- }
- else
+ if (monitor)
{
screen->scrn_monitor = monitor;
if (!xf86validateMonitor(p, screen))
@@ -526,15 +514,7 @@ xf86validateScreen (XF86ConfigPtr p)
}
}
- device = xf86findDevice (screen->scrn_device_str, p->conf_device_lst);
- if (!device)
- {
- xf86validationError (UNDEFINED_DEVICE_MSG,
- screen->scrn_device_str, screen->scrn_identifier);
- return (FALSE);
- }
- else
- screen->scrn_device = device;
+ screen->scrn_device= xf86findDevice (screen->scrn_device_str, p->conf_device_lst);
adaptor = screen->scrn_adaptor_lst;
while (adaptor)
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index 9f79696ac..430da0a5a 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -80,8 +80,6 @@ static xf86ConfigSymTabRec TopLevelTab[] =
static int
xf86validateConfig (XF86ConfigPtr p)
{
- if (!xf86validateDevice (p))
- return FALSE;
if (!xf86validateScreen (p))
return FALSE;
if (!xf86validateInput (p))
diff --git a/hw/xfree86/utils/xorgcfg/Makefile.am b/hw/xfree86/utils/xorgcfg/Makefile.am
index 309ed5c0a..e7113035f 100644
--- a/hw/xfree86/utils/xorgcfg/Makefile.am
+++ b/hw/xfree86/utils/xorgcfg/Makefile.am
@@ -33,7 +33,7 @@ INCLUDES = $(XORG_INCS) -I$(top_srcdir)/hw/xfree86/parser
OPTIONSPATH=$(libdir)/X11
-xorgcfg_CFLAGS = $(XORG_CFLAGS) $(CURSESDEFINES) \
+xorgcfg_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(CURSESDEFINES) \
$(XORGCFG_DEP_CFLAGS) -DXKB_RULES_DIR=\"$(XKB_BASE_DIRECTORY)/rules\" \
-DPROJECT_ROOT=\"$(PROJECTROOT)\" -DOPTIONSPATH=\"$(OPTIONSPATH)\"
xorgcfg_LDADD = $(XORGCFG_DEP_LIBS) ../../parser/libxf86config.a $(LOADERLIB) \
diff --git a/hw/xfree86/utils/xorgconfig/xorgconfig.c b/hw/xfree86/utils/xorgconfig/xorgconfig.c
index 8d9c03f5d..f50b4e225 100644
--- a/hw/xfree86/utils/xorgconfig/xorgconfig.c
+++ b/hw/xfree86/utils/xorgconfig/xorgconfig.c
@@ -631,7 +631,7 @@ mouse_configuration(void) {
config_emulate3buttons = 0;
printf("\n");
-#if (defined(sun) && (defined(__i386) || defined(__x86)))
+#if (defined(sun) && (defined(__i386__) || defined(__x86)))
/* SPARC & USB mice (VUID or AUTO protocols) default to /dev/mouse,
but PS/2 mice default to /dev/kdmouse */
if ((config_mousetype != M_AUTO) && (config_mousetype != M_VUID)) {
diff --git a/hw/xfree86/xf4bpp/vgaSolid.c b/hw/xfree86/xf4bpp/vgaSolid.c
index 501bd3db0..0ef18cfeb 100644
--- a/hw/xfree86/xf4bpp/vgaSolid.c
+++ b/hw/xfree86/xf4bpp/vgaSolid.c
@@ -54,7 +54,7 @@ static void fastFill
{
int stop_count = bytewidth ;
register int row_jump = bytes_per_line - bytewidth ;
-#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
+#if !defined(OLDHC) && defined(BSDrt) && !defined(__i386__)
register const unsigned int notZero = ((unsigned char)(~0x0));
#else
#define notZero ((unsigned char)(~0))
@@ -112,7 +112,7 @@ static void fastFillRMW
{
int stop_count = bytewidth ;
register int row_jump = bytes_per_line - bytewidth ;
-#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
+#if !defined(OLDHC) && defined(BSDrt) && !defined(__i386__)
register const unsigned int notZero = ((unsigned char)(~0x0));
#endif
register int tmp ;
@@ -369,7 +369,7 @@ register unsigned int height ; /* MUST BE > 0 !! */
{
int stop_count = wordwidth ;
register int row_jump = bytes_per_line - wordwidth*2 ;
-#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) && 0
+#if !defined(OLDHC) && defined(BSDrt) && !defined(__i386__) && 0
register const int notZero = ~0x0 ;
#else
#define notZero ( ~0 )
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index a091527f1..342d7417e 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -136,6 +136,9 @@
/* Define to 1 if you have the `getuid' function. */
#undef HAVE_GETUID
+/* Define to 1 if you have the `getzoneid' function. */
+#undef HAVE_GETZONEID
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -181,6 +184,9 @@
/* Define to 1 if you have the <rpcsvc/dbm.h> header file. */
#undef HAVE_RPCSVC_DBM_H
+/* Define to 1 if you have the `shmctl64' function. */
+#undef HAVE_SHMCTL64
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -425,6 +431,8 @@
/* Support DRI extension */
#undef XF86DRI
+#undef XEPHYR_DRI
+
/* Build DBE support */
#undef DBE
diff --git a/include/dix.h b/include/dix.h
index 59533bae7..09ed6d944 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -389,6 +389,9 @@ extern int DeliverDeviceEvents(
extern void DefineInitialRootWindow(
WindowPtr /* win */);
+extern void UpdateSpriteForScreen(
+ ScreenPtr /* pScreen */);
+
extern void WindowHasNewCursor(
WindowPtr /* pWin */);
diff --git a/include/os.h b/include/os.h
index 891f331c9..ac61992fe 100644
--- a/include/os.h
+++ b/include/os.h
@@ -323,6 +323,24 @@ extern int LocalClient(ClientPtr /* client */);
extern int LocalClientCred(ClientPtr, int *, int *);
+#define LCC_UID_SET (1 << 0)
+#define LCC_GID_SET (1 << 1)
+#define LCC_PID_SET (1 << 2)
+#define LCC_ZID_SET (1 << 3)
+
+typedef struct {
+ int fieldsSet; /* Bit mask of fields set */
+ int euid; /* Effective uid */
+ int egid; /* Primary effective group id */
+ int nSuppGids; /* Number of supplementary group ids */
+ int *pSuppGids; /* Array of supplementary group ids */
+ int pid; /* Process id */
+ int zoneid; /* Only set on Solaris 10 & later */
+} LocalClientCredRec;
+
+extern int GetLocalClientCreds(ClientPtr, LocalClientCredRec **);
+extern void FreeLocalClientCreds(LocalClientCredRec *);
+
extern int ChangeAccessControl(ClientPtr /*client*/, int /*fEnabled*/);
extern int GetAccessControl(void);
diff --git a/include/servermd.h b/include/servermd.h
index 74b90b38a..2616bfed6 100644
--- a/include/servermd.h
+++ b/include/servermd.h
@@ -260,7 +260,7 @@ SOFTWARE.
#if defined(ibm032) || defined (ibm)
-#ifdef i386
+#ifdef __i386__
# define IMAGE_BYTE_ORDER LSBFirst /* Value for PS/2 only */
#else
# define IMAGE_BYTE_ORDER MSBFirst /* Values for the RT only*/
@@ -270,7 +270,7 @@ SOFTWARE.
#define GETLEFTBITS_ALIGNMENT 4
/* ibm pcc doesn't understand pragmas. */
-#ifdef i386
+#ifdef __i386__
#define BITMAP_SCANLINE_UNIT 8
#endif
@@ -444,10 +444,9 @@ SOFTWARE.
#endif /* luna */
-#if (defined(SVR4) && defined(i386)) || \
+#if (defined(SVR4) && defined(__i386__)) || \
defined(__alpha__) || defined(__alpha) || \
- defined(__i386__) || defined(__i386) || \
- defined(__QNX__) || \
+ defined(__i386__) || defined(__QNX__) || \
defined(__s390x__) || defined(__s390__)
#ifndef IMAGE_BYTE_ORDER
diff --git a/mi/micoord.h b/mi/micoord.h
index b3d725b73..16a244b96 100644
--- a/mi/micoord.h
+++ b/mi/micoord.h
@@ -46,8 +46,7 @@
#if defined(mips) || defined(sgi) || \
defined(sparc) || defined(__sparc64__) || \
defined(__alpha) || defined(__alpha__) || \
- defined(__i386__) || defined(i386) || \
- defined(__ia64__) || defined(ia64) || \
+ defined(__i386__) || defined(__ia64__) || \
defined(__s390x__) || defined(__s390__) || \
defined(__amd64__) || defined(amd64) || defined(__amd64)
#define GetHighWord(x) (((int) (x)) >> 16)
diff --git a/mi/mipointer.c b/mi/mipointer.c
index 4d1db4fca..2c3c68913 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -255,6 +255,7 @@ miPointerWarpCursor (pScreen, x, y)
miPointer.y = y;
miPointer.pScreen = pScreen;
}
+ UpdateSpriteForScreen (pScreen) ;
}
/*
diff --git a/os/access.c b/os/access.c
index 33b2eb6a7..e91dd37e4 100644
--- a/os/access.c
+++ b/os/access.c
@@ -119,10 +119,10 @@ SOFTWARE.
# include <net/if.h>
# endif
#else
-#if defined(SVR4) || (defined(SYSV) && defined(i386)) || defined(__GNU__)
+#if defined(SVR4) || (defined(SYSV) && defined(__i386__)) || defined(__GNU__)
# include <sys/utsname.h>
#endif
-#if defined(SYSV) && defined(i386)
+#if defined(SYSV) && defined(__i386__)
# include <sys/stream.h>
# ifdef ISC
# include <sys/stropts.h>
@@ -234,10 +234,6 @@ static Bool NewHost(int /*family*/,
int /*len*/,
int /* addingLocalHosts */);
-static int LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
- int **pSuppGids, int *nSuppGids);
-
-
/* XFree86 bug #156: To keep track of which hosts were explicitly requested in
/etc/X<display>.hosts, we've added a requested field to the HOST struct,
and a LocalHostRequested variable. These default to FALSE, but are set
@@ -1383,38 +1379,51 @@ _X_EXPORT Bool LocalClient(ClientPtr client)
/*
* Return the uid and gid of a connected local client
- * or the uid/gid for nobody those ids cannot be determined
*
* Used by XShm to test access rights to shared memory segments
*/
int
LocalClientCred(ClientPtr client, int *pUid, int *pGid)
{
- return LocalClientCredAndGroups(client, pUid, pGid, NULL, NULL);
+ LocalClientCredRec *lcc;
+ int ret = GetLocalClientCreds(client, &lcc);
+
+ if (ret == 0) {
+#ifdef HAVE_GETZONEID /* only local if in the same zone */
+ if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+#endif
+ if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL))
+ *pUid = lcc->euid;
+ if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL))
+ *pGid = lcc->egid;
+ FreeLocalClientCreds(lcc);
+ }
+ return ret;
}
/*
* Return the uid and all gids of a connected local client
- * or the uid/gid for nobody those ids cannot be determined
+ * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
*
- * If the caller passes non-NULL values for pSuppGids & nSuppGids,
- * they are responsible for calling XFree(*pSuppGids) to release the
- * memory allocated for the supplemental group ids list.
- *
* Used by localuser & localgroup ServerInterpreted access control forms below
+ * Used by AuthAudit to log who local connections came from
*/
-static int
-LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
- int **pSuppGids, int *nSuppGids)
+int
+GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
{
#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
int fd;
XtransConnInfo ci;
+ LocalClientCredRec *lcc;
#ifdef HAS_GETPEEREID
uid_t uid;
gid_t gid;
#elif defined(HAS_GETPEERUCRED)
ucred_t *peercred = NULL;
+ const gid_t *gids;
#elif defined(SO_PEERCRED)
struct ucred peercred;
socklen_t so_len = sizeof(peercred);
@@ -1433,57 +1442,65 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
}
#endif
- if (pSuppGids != NULL)
- *pSuppGids = NULL;
- if (nSuppGids != NULL)
- *nSuppGids = 0;
-
+ *lccp = Xcalloc(sizeof(LocalClientCredRec));
+ if (*lccp == NULL)
+ return -1;
+ lcc = *lccp;
+
fd = _XSERVTransGetConnectionNumber(ci);
#ifdef HAS_GETPEEREID
- if (getpeereid(fd, &uid, &gid) == -1)
- return -1;
- if (pUid != NULL)
- *pUid = uid;
- if (pGid != NULL)
- *pGid = gid;
+ if (getpeereid(fd, &uid, &gid) == -1) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+ lcc->euid = uid;
+ lcc->egid = gid;
+ lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
return 0;
#elif defined(HAS_GETPEERUCRED)
- if (getpeerucred(fd, &peercred) < 0)
+ if (getpeerucred(fd, &peercred) < 0) {
+ FreeLocalClientCreds(lcc);
return -1;
-#ifdef sun /* Ensure process is in the same zone */
- if (getzoneid() != ucred_getzoneid(peercred)) {
- ucred_free(peercred);
- return -1;
}
-#endif
- if (pUid != NULL)
- *pUid = ucred_geteuid(peercred);
- if (pGid != NULL)
- *pGid = ucred_getegid(peercred);
- if (pSuppGids != NULL && nSuppGids != NULL) {
- const gid_t *gids;
- *nSuppGids = ucred_getgroups(peercred, &gids);
- if (*nSuppGids > 0) {
- *pSuppGids = xalloc(sizeof(int) * (*nSuppGids));
- if (*pSuppGids == NULL) {
- *nSuppGids = 0;
- } else {
- int i;
- for (i = 0 ; i < *nSuppGids; i++) {
- (*pSuppGids)[i] = (int) gids[i];
- }
+ lcc->euid = ucred_geteuid(peercred);
+ if (lcc->euid != -1)
+ lcc->fieldsSet |= LCC_UID_SET;
+ lcc->egid = ucred_getegid(peercred);
+ if (lcc->egid != -1)
+ lcc->fieldsSet |= LCC_GID_SET;
+ lcc->pid = ucred_getpid(peercred);
+ if (lcc->pid != -1)
+ lcc->fieldsSet |= LCC_PID_SET;
+#ifdef HAVE_GETZONEID
+ lcc->zoneid = ucred_getzoneid(peercred);
+ if (lcc->zoneid != -1)
+ lcc->fieldsSet |= LCC_ZID_SET;
+#endif
+ lcc->nSuppGids = ucred_getgroups(peercred, &gids);
+ if (lcc->nSuppGids > 0) {
+ lcc->pSuppGids = Xcalloc((lcc->nSuppGids) * sizeof(int));
+ if (lcc->pSuppGids == NULL) {
+ lcc->nSuppGids = 0;
+ } else {
+ int i;
+ for (i = 0 ; i < lcc->nSuppGids; i++) {
+ (lcc->pSuppGids)[i] = (int) gids[i];
}
}
+ } else {
+ lcc->nSuppGids = 0;
}
ucred_free(peercred);
return 0;
#elif defined(SO_PEERCRED)
- if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1)
- return -1;
- if (pUid != NULL)
- *pUid = peercred.uid;
- if (pGid != NULL)
- *pGid = peercred.gid;
+ if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+ lcc->euid = peercred.uid;
+ lcc->egid = peercred.gid;
+ lcc->pid = peercred.pid;
+ lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
return 0;
#endif
#else
@@ -1493,6 +1510,17 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
#endif
}
+void
+FreeLocalClientCreds(LocalClientCredRec *lcc)
+{
+ if (lcc != NULL) {
+ if (lcc->nSuppGids > 0) {
+ Xfree(lcc->pSuppGids);
+ }
+ Xfree(lcc);
+ }
+}
+
static int
AuthorizedClient(ClientPtr client)
{
@@ -2327,38 +2355,48 @@ static Bool
siLocalCredAddrMatch(int family, pointer addr, int len,
const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
{
- int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId;
+ int siAddrId;
+ LocalClientCredRec *lcc;
siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
- if (LocalClientCredAndGroups(client, &connUid, &connGid,
- &connSuppGids, &connNumSuppGids) == -1) {
+ if (GetLocalClientCreds(client, &lcc) == -1) {
return FALSE;
}
+#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
+ if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+ FreeLocalClientCreds(lcc);
+ return FALSE;
+ }
+#endif
+
if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
+ FreeLocalClientCreds(lcc);
return FALSE;
}
if (lcPriv->credType == LOCAL_USER) {
- if (connUid == siAddrId) {
+ if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
+ FreeLocalClientCreds(lcc);
return TRUE;
}
} else {
- if (connGid == siAddrId) {
+ if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
+ FreeLocalClientCreds(lcc);
return TRUE;
}
- if (connSuppGids != NULL) {
+ if (lcc->pSuppGids != NULL) {
int i;
- for (i = 0 ; i < connNumSuppGids; i++) {
- if (connSuppGids[i] == siAddrId) {
- xfree(connSuppGids);
+ for (i = 0 ; i < lcc->nSuppGids; i++) {
+ if (lcc->pSuppGids[i] == siAddrId) {
+ FreeLocalClientCreds(lcc);
return TRUE;
}
}
- xfree(connSuppGids);
}
}
+ FreeLocalClientCreds(lcc);
return FALSE;
}
diff --git a/os/connection.c b/os/connection.c
index 3d9d2e919..357878100 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -536,10 +536,8 @@ AuthAudit (ClientPtr client, Bool letin,
char *out = addr;
int client_uid;
char client_uid_string[64];
-#ifdef HAS_GETPEERUCRED
- ucred_t *peercred = NULL;
-#endif
-#if defined(HAS_GETPEERUCRED) || defined(XSERVER_DTRACE)
+ LocalClientCredRec *lcc;
+#ifdef XSERVER_DTRACE
pid_t client_pid = -1;
zoneid_t client_zid = -1;
#endif
@@ -580,23 +578,50 @@ AuthAudit (ClientPtr client, Bool letin,
strcpy(out, "unknown address");
}
-#ifdef HAS_GETPEERUCRED
- if (getpeerucred(((OsCommPtr)client->osPrivate)->fd, &peercred) >= 0) {
- client_uid = ucred_geteuid(peercred);
- client_pid = ucred_getpid(peercred);
- client_zid = ucred_getzoneid(peercred);
-
- ucred_free(peercred);
- snprintf(client_uid_string, sizeof(client_uid_string),
- " (uid %ld, pid %ld, zone %ld)",
- (long) client_uid, (long) client_pid, (long) client_zid);
- }
-#else
- if (LocalClientCred(client, &client_uid, NULL) != -1) {
- snprintf(client_uid_string, sizeof(client_uid_string),
- " (uid %d)", client_uid);
- }
+ if (GetLocalClientCreds(client, &lcc) != -1) {
+ int slen; /* length written to client_uid_string */
+
+ strcpy(client_uid_string, " ( ");
+ slen = 3;
+
+ if (lcc->fieldsSet & LCC_UID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "uid=%ld ", (long) lcc->euid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_GID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "gid=%ld ", (long) lcc->egid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_PID_SET) {
+#ifdef XSERVER_DTRACE
+ client_pid = lcc->pid;
#endif
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "pid=%ld ", (long) lcc->pid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_ZID_SET) {
+#ifdef XSERVER_DTRACE
+ client_zid = lcc->zoneid;
+#endif
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "zoneid=%ld ", (long) lcc->zoneid);
+ slen = strlen(client_uid_string);
+ }
+
+ snprintf(client_uid_string + slen, sizeof(client_uid_string) - slen,
+ ")");
+ FreeLocalClientCreds(lcc);
+ }
else {
client_uid_string[0] = '\0';
}
diff --git a/os/io.c b/os/io.c
index 9de75eeaa..36abe1332 100644
--- a/os/io.c
+++ b/os/io.c
@@ -356,7 +356,7 @@ ReadRequestFromClient(ClientPtr client)
{
if ((result < 0) && ETEST(errno))
{
-#if defined(SVR4) && defined(i386) && !defined(sun)
+#if defined(SVR4) && defined(__i386__) && !defined(sun)
if (0)
#endif
{
diff --git a/os/utils.c b/os/utils.c
index 36c8dfeb3..31cb0af92 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -160,6 +160,7 @@ _X_EXPORT Bool noFontCacheExtension = FALSE;
#endif
#ifdef GLXEXT
_X_EXPORT Bool noGlxExtension = FALSE;
+_X_EXPORT Bool noGlxVisualInit = FALSE;
#endif
#ifdef SCREENSAVER
_X_EXPORT Bool noScreenSaverExtension = FALSE;
diff --git a/os/xalloc.c b/os/xalloc.c
index 8c019f3bc..e5f39465b 100644
--- a/os/xalloc.c
+++ b/os/xalloc.c
@@ -211,7 +211,7 @@ extern Bool Must_have_memory;
fclose(f); \
} \
}
-#if defined(linux) && defined(i386)
+#if defined(linux) && defined(__i386__)
#define LOG_ALLOC(_fun, _size, _ret) \
{ unsigned long *from; \
__asm__("movl %%ebp,%0" : /*OUT*/ "=r" (from) : /*IN*/ ); \
diff --git a/xorg-server.pc.in b/xorg-server.pc.in
index d3ffaa2f8..c1cdb7d2a 100644
--- a/xorg-server.pc.in
+++ b/xorg-server.pc.in
@@ -8,6 +8,6 @@ sdkdir=@sdkdir@
Name: xorg-server
Description: Modular X.Org X Server
Version: @PACKAGE_VERSION@
-Requires.private: pixman-1
+Requires: pixman-1
Cflags: -I${sdkdir}
Libs: -L${libdir}