From c40e0b51f0d9ef5e1f30f233d7db1e6db9d6681b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 26 Mar 2008 19:28:09 -0400 Subject: [PATCH 01/34] Implement DRI2 direct rendering and update AIGLX to DRI interface changes. Get rid of glcontextmodes.[ch] from build, rename __GlcontextModes to __GLXcontext. Drop all #includes of glcontextmodes.h and glcore.h. Drop the DRI context modes extension. Add protocol code to DRI2 module and load DRI2 extension by default. --- GL/glx/Makefile.am | 2 - GL/glx/glxcmds.c | 51 ++-- GL/glx/glxcontext.h | 6 +- GL/glx/glxdrawable.h | 2 +- GL/glx/glxdri.c | 257 ++++++++++---------- GL/glx/glxdri2.c | 427 ++++++++++++++++++++++----------- GL/glx/glxglcore.c | 56 +++-- GL/glx/glxscreens.c | 55 +++-- GL/glx/glxscreens.h | 88 ++++++- GL/glx/glxutil.c | 5 +- GL/glx/glxutil.h | 2 +- GL/symlink-mesa.sh | 2 - configure.ac | 2 +- hw/xfree86/common/xf86Config.c | 1 + hw/xfree86/dri2/Makefile.am | 5 +- hw/xfree86/dri2/dri2.c | 107 ++++++--- hw/xfree86/dri2/dri2.h | 16 +- hw/xfree86/dri2/dri2ext.c | 361 ++++++++++++++++++++++++++++ os/utils.c | 3 + 19 files changed, 1054 insertions(+), 394 deletions(-) create mode 100644 hw/xfree86/dri2/dri2ext.c diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am index 377d760199..1d4719c88f 100644 --- a/GL/glx/Makefile.am +++ b/GL/glx/Makefile.am @@ -31,8 +31,6 @@ INCLUDES = \ nodist_libglx_la_SOURCES = indirect_size.h \ glapi.c \ - glcontextmodes.c \ - glcontextmode.h \ glthread.c \ indirect_dispatch.c \ indirect_dispatch.h \ diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 3b79cca205..36aae61b9f 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -50,7 +50,6 @@ #include #include "glxutil.h" #include "glxext.h" -#include "glcontextmodes.h" #include "glapitable.h" #include "glapi.h" #include "glthread.h" @@ -83,9 +82,9 @@ validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) static int validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, - __GLcontextModes **config, int *err) + __GLXconfig **config, int *err) { - __GLcontextModes *m; + __GLXconfig *m; for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) if (m->fbconfigID == id) { @@ -101,7 +100,7 @@ validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, static int validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, - __GLcontextModes **config, int *err) + __GLXconfig **config, int *err) { int i; @@ -118,7 +117,7 @@ validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, } static int -validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config, +validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config, DrawablePtr pDraw, int *err) { ScreenPtr pScreen = pDraw->pScreen; @@ -135,7 +134,7 @@ validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config, } /* FIXME: What exactly should we check here... */ - if (pVisual->class != _gl_convert_to_x_visual_type(config->visualType) || + if (pVisual->class != glxConvertToXVisualType(config->visualType) || !(config->drawableType & GLX_WINDOW_BIT)) { client->errorValue = pDraw->id; *err = BadMatch; @@ -161,7 +160,7 @@ static void __glXdirectContextDestroy(__GLXcontext *context) } static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, - __GLcontextModes *modes, + __GLXconfig *modes, __GLXcontext *shareContext) { __GLXcontext *context; @@ -186,7 +185,7 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, static int DoCreateContext(__GLXclientState *cl, GLXContextID gcId, - GLXContextID shareList, __GLcontextModes *config, + GLXContextID shareList, __GLXconfig *config, __GLXscreen *pGlxScreen, GLboolean isDirect) { ClientPtr client = cl->client; @@ -248,7 +247,7 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, ** a GL core that needs windowing information (e.g., Mesa). */ glxc->pGlxScreen = pGlxScreen; - glxc->modes = config; + glxc->config = config; /* ** Register this context as a resource. @@ -276,7 +275,7 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -292,7 +291,7 @@ int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -309,7 +308,7 @@ int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -462,7 +461,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, * GLXPixmap and we just return the __GLXdrawable. */ pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes); if (pGlxDraw != NULL) { - if (glxc != NULL && pGlxDraw->modes != glxc->modes) { + if (glxc != NULL && pGlxDraw->config != glxc->config) { client->errorValue = drawId; *error = BadMatch; return NULL; @@ -497,12 +496,12 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, * the context screen and that the context fbconfig is compatible * with the window visual. */ if (pDraw->pScreen != glxc->pGlxScreen->pScreen || - !validGlxFBConfigForWindow(client, glxc->modes, pDraw, error)) + !validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) return NULL; pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, pDraw, GLX_DRAWABLE_WINDOW, - drawId, glxc->modes); + drawId, glxc->config); /* since we are creating the drawablePrivate, drawId should be new */ if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { @@ -878,7 +877,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) ClientPtr client = cl->client; xGLXGetVisualConfigsReply reply; __GLXscreen *pGlxScreen; - __GLcontextModes *modes; + __GLXconfig *modes; CARD32 buf[__GLX_TOTAL_CONFIG]; int p, i, err; __GLX_DECLARE_SWAP_VARIABLES; @@ -907,7 +906,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) p = 0; buf[p++] = modes->visualID; - buf[p++] = _gl_convert_to_x_visual_type( modes->visualType ); + buf[p++] = glxConvertToXVisualType( modes->visualType ); buf[p++] = modes->rgbMode; buf[p++] = modes->redBits; @@ -980,7 +979,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) __GLXscreen *pGlxScreen; CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; int p, err; - __GLcontextModes *modes; + __GLXconfig *modes; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; @@ -1062,7 +1061,7 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) } static int -DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, +DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, DrawablePtr pDraw, XID glxDrawableId, int type) { __GLXdrawable *pGlxDraw; @@ -1086,7 +1085,7 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes } static int -DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, +DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, XID drawableId, XID glxDrawableId) { DrawablePtr pDraw; @@ -1144,7 +1143,7 @@ determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs) int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -1160,7 +1159,7 @@ int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -1184,7 +1183,7 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapWithConfigSGIXReq *req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -1246,7 +1245,7 @@ static int DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, int width, int height, XID glxDrawableId) { - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; PixmapPtr pPixmap; int err; @@ -1359,7 +1358,7 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) { xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; ClientPtr client = cl->client; DrawablePtr pDraw; @@ -1473,7 +1472,7 @@ DoQueryContext(__GLXclientState *cl, GLXContextID gcId) *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; *pSendBuf++ = (int)(ctx->share_id); *pSendBuf++ = GLX_VISUAL_ID_EXT; - *pSendBuf++ = (int)(ctx->modes->visualID); + *pSendBuf++ = (int)(ctx->config->visualID); *pSendBuf++ = GLX_SCREEN_EXT; *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum); diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h index 4c36801c14..18d3c6fe5c 100644 --- a/GL/glx/glxcontext.h +++ b/GL/glx/glxcontext.h @@ -40,8 +40,6 @@ ** */ -#include "GL/internal/glcore.h" - typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap; struct __GLXtextureFromPixmap { int (*bindTexImage) (__GLXcontext *baseContext, @@ -77,9 +75,9 @@ struct __GLXcontext { __GLXcontext *nextReadPriv; /* - ** mode struct for this context + ** config struct for this context */ - __GLcontextModes *modes; + __GLXconfig *config; /* ** Pointer to screen info data for this context. This is set diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h index f62d1ee34f..98e301b88d 100644 --- a/GL/glx/glxdrawable.h +++ b/GL/glx/glxdrawable.h @@ -74,7 +74,7 @@ struct __GLXdrawable { /* ** Configuration of the visual to which this drawable was created. */ - __GLcontextModes *modes; + __GLXconfig *config; /* ** Lists of contexts bound to this drawable. There are two lists here. diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index 1e17911229..ffa9a0b766 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -52,7 +52,6 @@ #define DRI_NEW_INTERFACE_ONLY #include "glxserver.h" #include "glxutil.h" -#include "glcontextmodes.h" #include "g_disptab.h" #include "glapitable.h" @@ -61,26 +60,26 @@ #include "dispatch.h" #include "extension_string.h" -#define containerOf(ptr, type, member) \ - (type *)( (char *)ptr - offsetof(type,member) ) - typedef struct __GLXDRIscreen __GLXDRIscreen; typedef struct __GLXDRIcontext __GLXDRIcontext; typedef struct __GLXDRIdrawable __GLXDRIdrawable; +typedef struct __GLXDRIconfig __GLXDRIconfig; struct __GLXDRIscreen { __GLXscreen base; - __DRIscreen driScreen; + __DRIscreen *driScreen; void *driver; xf86EnterVTProc *enterVT; xf86LeaveVTProc *leaveVT; - __DRIcopySubBufferExtension *copySubBuffer; - __DRIswapControlExtension *swapControl; + const __DRIcoreExtension *core; + const __DRIlegacyExtension *legacy; + const __DRIcopySubBufferExtension *copySubBuffer; + const __DRIswapControlExtension *swapControl; #ifdef __DRI_TEX_OFFSET - __DRItexOffsetExtension *texOffset; + const __DRItexOffsetExtension *texOffset; DRITexOffsetStartProcPtr texOffsetStart; DRITexOffsetFinishProcPtr texOffsetFinish; __GLXDRIdrawable *texOffsetOverride[16]; @@ -92,13 +91,13 @@ struct __GLXDRIscreen { struct __GLXDRIcontext { __GLXcontext base; - __DRIcontext driContext; + __DRIcontext *driContext; XID hwContextID; }; struct __GLXDRIdrawable { __GLXdrawable base; - __DRIdrawable driDrawable; + __DRIdrawable *driDrawable; /* Pulled in from old __GLXpixmap */ #ifdef __DRI_TEX_OFFSET @@ -109,7 +108,10 @@ struct __GLXDRIdrawable { #endif }; -static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING; +struct __GLXDRIconfig { + __GLXconfig config; + __DRIconfig *driConfig; +}; static void __glXDRIleaveServer(GLboolean rendering) @@ -151,7 +153,7 @@ __glXDRIleaveServer(GLboolean rendering) __GLXDRIdrawable *pGlxPix = texOffsetOverride[j]; if (pGlxPix && pGlxPix->texname) { - screen->texOffset->setTexOffset(&pGlxPix->ctx->driContext, + screen->texOffset->setTexOffset(pGlxPix->ctx->driContext, pGlxPix->texname, pGlxPix->offset, pGlxPix->base.pDraw->depth, @@ -219,24 +221,24 @@ static void __glXDRIdrawableDestroy(__GLXdrawable *drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - + __GLXDRIscreen *screen; int i; for (i = 0; i < screenInfo.numScreens; i++) { - __glXDRIdoReleaseTexImage((__GLXDRIscreen *) - glxGetScreen(screenInfo.screens[i]), - private); + screen = (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]); + __glXDRIdoReleaseTexImage(screen, private); } - (*private->driDrawable.destroyDrawable)(&private->driDrawable); - /* If the X window was destroyed, the dri DestroyWindow hook will * aready have taken care of this, so only call if pDraw isn't NULL. */ if (drawable->pDraw != NULL) { - __glXenterServer(GL_FALSE); - DRIDestroyDrawable(drawable->pDraw->pScreen, - serverClient, drawable->pDraw); - __glXleaveServer(GL_FALSE); + screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen); + (*screen->core->destroyDrawable)(private->driDrawable); + + __glXenterServer(GL_FALSE); + DRIDestroyDrawable(drawable->pDraw->pScreen, + serverClient, drawable->pDraw); + __glXleaveServer(GL_FALSE); } xfree(private); @@ -255,8 +257,10 @@ static GLboolean __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; + __GLXDRIscreen *screen = + (__GLXDRIscreen *) glxGetScreen(basePrivate->pDraw->pScreen); - (*private->driDrawable.swapBuffers)(&private->driDrawable); + (*screen->core->swapBuffers)(private->driDrawable); return TRUE; } @@ -266,11 +270,11 @@ static int __glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval) { __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable; - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(baseDrawable->pDraw->pScreen); + __GLXDRIscreen *screen = + (__GLXDRIscreen *) glxGetScreen(baseDrawable->pDraw->pScreen); if (screen->swapControl) - screen->swapControl->setSwapInterval(&draw->driDrawable, interval); + screen->swapControl->setSwapInterval(draw->driDrawable, interval); return 0; } @@ -285,20 +289,21 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, glxGetScreen(basePrivate->pDraw->pScreen); if (screen->copySubBuffer) - screen->copySubBuffer->copySubBuffer(&private->driDrawable, - x, y, w, h); + screen->copySubBuffer->copySubBuffer(private->driDrawable, x, y, w, h); } static void __glXDRIcontextDestroy(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; Bool retval; - context->driContext.destroyContext(&context->driContext); + screen->core->destroyContext(context->driContext); __glXenterServer(GL_FALSE); - retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen, context->hwContextID); + retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen, + context->hwContextID); __glXleaveServer(GL_FALSE); __glXContextDestroy(&context->base); @@ -309,20 +314,22 @@ static int __glXDRIcontextMakeCurrent(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } static int __glXDRIcontextLoseCurrent(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.unbindContext)(&context->driContext); + return (*screen->core->unbindContext)(context->driContext); } static int @@ -331,13 +338,10 @@ __glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, { __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; + __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; - /* FIXME: We will need to add DRIcontext::copyContext for this. */ - - (void) dst; - (void) src; - - return FALSE; + return (*screen->core->copyContext)(dst->driContext, + src->driContext, mask); } static int @@ -346,10 +350,11 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } static void @@ -392,10 +397,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, int bpp, override = 0, texname; GLenum format, type; ScreenPtr pScreen = glxPixmap->pDraw->pScreen; - __GLXDRIdrawable *driDraw = - containerOf(glxPixmap, __GLXDRIdrawable, base); - __GLXDRIscreen * const screen = - (__GLXDRIscreen *) glxGetScreen(pScreen); + __GLXDRIdrawable *driDraw = (__GLXDRIdrawable *) glxPixmap; + __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen); CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : @@ -439,7 +442,7 @@ alreadyin: driDraw->texname = texname; - screen->texOffset->setTexOffset(&driDraw->ctx->driContext, texname, 0, + screen->texOffset->setTexOffset(driDraw->ctx->driContext, texname, 0, pixmap->drawable.depth, pixmap->devKind); } @@ -568,9 +571,11 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext, int buffer, __GLXdrawable *pixmap) { - __glXDRIdoReleaseTexImage((__GLXDRIscreen *) - glxGetScreen(pixmap->pDraw->pScreen), - containerOf(pixmap, __GLXDRIdrawable, base)); + __GLXDRIscreen *screen = + (__GLXDRIscreen *) glxGetScreen(pixmap->pDraw->pScreen); + __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) pixmap; + + __glXDRIdoReleaseTexImage(screen, drawable); return Success; } @@ -585,7 +590,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - screen->driScreen.destroyScreen(&screen->driScreen); + screen->core->destroyScreen(screen->driScreen); dlclose(screen->driver); @@ -596,11 +601,12 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) static __GLXcontext * __glXDRIscreenCreateContext(__GLXscreen *baseScreen, - __GLcontextModes *modes, + __GLXconfig *glxConfig, __GLXcontext *baseShareContext) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; __GLXDRIcontext *context, *shareContext; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; VisualPtr visual; int i; GLboolean retval; @@ -610,7 +616,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, shareContext = (__GLXDRIcontext *) baseShareContext; if (shareContext) - driShare = &shareContext->driContext; + driShare = shareContext->driContext; else driShare = NULL; @@ -632,7 +638,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, /* Find the requested X visual */ visual = pScreen->visuals; for (i = 0; i < pScreen->numVisuals; i++, visual++) - if (visual->vid == modes->visualID) + if (visual->vid == glxConfig->visualID) break; if (i == pScreen->numVisuals) return GL_FALSE; @@ -644,15 +650,15 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, context->hwContextID, &hwContext); __glXleaveServer(GL_FALSE); - context->driContext.private = - screen->driScreen.createNewContext(&screen->driScreen, - modes, - 0, /* render type */ - driShare, - hwContext, - &context->driContext); + context->driContext = + screen->legacy->createNewContext(screen->driScreen, + config->driConfig, + 0, /* render type */ + driShare, + hwContext, + context); - if (context->driContext.private == NULL) { + if (context->driContext == NULL) { __glXenterServer(GL_FALSE); retval = DRIDestroyContext(baseScreen->pScreen, context->hwContextID); __glXleaveServer(GL_FALSE); @@ -668,9 +674,10 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes) + __GLXconfig *glxConfig) { __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __GLXDRIdrawable *private; GLboolean retval; drm_drawable_t hwDrawable; @@ -682,7 +689,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, memset(private, 0, sizeof *private); if (!__glXDrawableInit(&private->base, screen, - pDraw, type, drawId, modes)) { + pDraw, type, drawId, glxConfig)) { xfree(private); return NULL; } @@ -700,13 +707,12 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, /* The last argument is 'attrs', which is used with pbuffers which * we currently don't support. */ - private->driDrawable.private = - (driScreen->driScreen.createNewDrawable)(&driScreen->driScreen, - modes, - &private->driDrawable, - hwDrawable, 0, 0, NULL); + private->driDrawable = + (driScreen->legacy->createNewDrawable)(driScreen->driScreen, + config->driConfig, + hwDrawable, 0, NULL, private); - if (private->driDrawable.private == NULL) { + if (private->driDrawable == NULL) { __glXenterServer(GL_FALSE); DRIDestroyDrawable(screen->pScreen, serverClient, pDraw); __glXleaveServer(GL_FALSE); @@ -723,10 +729,10 @@ getDrawableInfo(__DRIdrawable *driDrawable, 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) + int *numBackClipRects, drm_clip_rect_t **ppBackClipRects, + void *data) { - __GLXDRIdrawable *drawable = containerOf(driDrawable, - __GLXDRIdrawable, driDrawable); + __GLXDRIdrawable *drawable = data; ScreenPtr pScreen; drm_clip_rect_t *pClipRects, *pBackClipRects; GLboolean retval; @@ -810,10 +816,10 @@ getUST(int64_t *ust) static void __glXReportDamage(__DRIdrawable *driDraw, int x, int y, drm_clip_rect_t *rects, int num_rects, - GLboolean front_buffer) + GLboolean front_buffer, + void *data) { - __GLXDRIdrawable *drawable = - containerOf(driDraw, __GLXDRIdrawable, driDrawable); + __GLXDRIdrawable *drawable = data; DrawablePtr pDraw = drawable->base.pDraw; RegionRec region; @@ -827,13 +833,6 @@ static void __glXReportDamage(__DRIdrawable *driDraw, __glXleaveServer(GL_FALSE); } -/* Table of functions that we export to the driver. */ -static const __DRIcontextModesExtension contextModesExtension = { - { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, - _gl_context_modes_create, - _gl_context_modes_destroy, -}; - static const __DRIsystemTimeExtension systemTimeExtension = { { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, getUST, @@ -851,7 +850,6 @@ static const __DRIdamageExtension damageExtension = { }; static const __DRIextension *loader_extensions[] = { - &contextModesExtension.base, &systemTimeExtension.base, &getDrawableInfoExtension.base, &damageExtension.base, @@ -897,7 +895,8 @@ initializeExtensions(__GLXDRIscreen *screen) const __DRIextension **extensions; int i; - extensions = screen->driScreen.getExtensions(&screen->driScreen); + extensions = screen->core->getExtensions(screen->driScreen); + for (i = 0; extensions[i]; i++) { #ifdef __DRI_COPY_SUB_BUFFER if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { @@ -931,12 +930,12 @@ initializeExtensions(__GLXDRIscreen *screen) } } -#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314 +extern __GLXconfig * +glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs); static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { - PFNCREATENEWSCREENFUNC createNewScreen; drm_handle_t hSAREA; drmAddress pSAREA = NULL; char *BusID; @@ -953,11 +952,13 @@ __glXDRIscreenProbe(ScreenPtr pScreen) drm_handle_t hFB; int junk; __GLXDRIscreen *screen; - void *dev_priv = NULL; char filename[128]; Bool isCapable; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + const __DRIconfig **driConfigs; + const __DRIextension **extensions; + int i; if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") || !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || @@ -985,9 +986,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) dri_version.minor = XF86DRI_MINOR_VERSION; dri_version.patch = XF86DRI_PATCH_VERSION; - framebuffer.base = NULL; - framebuffer.dev_priv = NULL; - if (!DRIOpenConnection(pScreen, &hSAREA, &BusID)) { LogMessage(X_ERROR, "AIGLX error: DRIOpenConnection failed\n"); goto handle_error; @@ -1046,11 +1044,30 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC); - if (createNewScreen == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n", - CREATE_NEW_SCREEN_FUNC, dlerror()); - goto handle_error; + extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", + driverName, dlerror()); + goto handle_error; + } + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && + extensions[i]->version >= __DRI_CORE_VERSION) { + screen->core = (__DRIcoreExtension *) extensions[i]; + } + + if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 && + extensions[i]->version >= __DRI_LEGACY_VERSION) { + screen->legacy = (__DRIlegacyExtension *) extensions[i]; + } + } + + if (screen->core == NULL || screen->legacy == NULL) { + LogMessage(X_ERROR, + "AIGLX error: %s does not export required DRI extension\n", + driverName); + goto handle_error; } /* @@ -1066,19 +1083,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - /* Sigh... the DRI interface is broken; the DRI driver will free - * the dev private pointer using _mesa_free() on screen destroy, - * but we can't use _mesa_malloc() here. In fact, the DRI driver - * shouldn't free data it didn't allocate itself, but what can you - * do... */ - dev_priv = xalloc(framebuffer.dev_priv_size); - if (dev_priv == NULL) { - LogMessage(X_ERROR, "AIGLX error: dev_priv allocation failed"); - goto handle_error; - } - memcpy(dev_priv, framebuffer.dev_priv, framebuffer.dev_priv_size); - framebuffer.dev_priv = dev_priv; - framebuffer.width = pScreen->width; framebuffer.height = pScreen->height; @@ -1101,28 +1105,30 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - screen->driScreen.private = - (*createNewScreen)(pScreen->myNum, - &screen->driScreen, - &ddx_version, - &dri_version, - &drm_version, - &framebuffer, - pSAREA, - fd, - loader_extensions, - &screen->base.fbconfigs); + screen->driScreen = + (*screen->legacy->createNewScreen)(pScreen->myNum, + &ddx_version, + &dri_version, + &drm_version, + &framebuffer, + pSAREA, + fd, + loader_extensions, + &driConfigs, + screen); - if (screen->driScreen.private == NULL) { + screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); + + if (screen->driScreen == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); goto handle_error; } + initializeExtensions(screen); + DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart, &screen->texOffsetFinish); - initializeExtensions(screen); - __glXScreenInit(&screen->base, pScreen); buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); @@ -1155,9 +1161,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) if (framebuffer.base != NULL) drmUnmap((drmAddress)framebuffer.base, framebuffer.size); - if (dev_priv != NULL) - xfree(dev_priv); - if (fd >= 0) drmCloseOnce(fd); diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c index fecfb1977f..40590c167d 100644 --- a/GL/glx/glxdri2.c +++ b/GL/glx/glxdri2.c @@ -35,20 +35,18 @@ #include #include #include +#include #include #include #define _XF86DRI_SERVER_ #include -#include -#include #include #include #include "glxserver.h" #include "glxutil.h" -#include "glcontextmodes.h" #include "g_disptab.h" #include "glapitable.h" @@ -57,53 +55,56 @@ #include "dispatch.h" #include "extension_string.h" -#define containerOf(ptr, type, member) \ - (type *)( (char *)ptr - offsetof(type,member) ) - typedef struct __GLXDRIscreen __GLXDRIscreen; typedef struct __GLXDRIcontext __GLXDRIcontext; typedef struct __GLXDRIdrawable __GLXDRIdrawable; +typedef struct __GLXDRIconfig __GLXDRIconfig; struct __GLXDRIscreen { __GLXscreen base; - __DRIscreen driScreen; + __DRIscreen *driScreen; void *driver; int fd; xf86EnterVTProc *enterVT; xf86LeaveVTProc *leaveVT; - __DRIcopySubBufferExtension *copySubBuffer; - __DRIswapControlExtension *swapControl; - __DRItexBufferExtension *texBuffer; + const __DRIcoreExtension *core; + const __DRIcopySubBufferExtension *copySubBuffer; + const __DRIswapControlExtension *swapControl; + const __DRItexBufferExtension *texBuffer; unsigned char glx_enable_bits[__GLX_EXT_BYTES]; }; struct __GLXDRIcontext { - __GLXcontext base; - __DRIcontext driContext; - drm_context_t hwContext; + __GLXcontext base; + __DRIcontext *driContext; }; struct __GLXDRIdrawable { - __GLXdrawable base; - __DRIdrawable driDrawable; + __GLXdrawable base; + __DRIdrawable *driDrawable; + __GLXDRIscreen *screen; }; -static const char CREATE_NEW_SCREEN_FUNC[] = __DRI2_CREATE_NEW_SCREEN_STRING; +struct __GLXDRIconfig { + __GLXconfig config; + const __DRIconfig *driConfig; +}; static void __glXDRIdrawableDestroy(__GLXdrawable *drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - - (*private->driDrawable.destroyDrawable)(&private->driDrawable); + const __DRIcoreExtension *core = private->screen->core; + + (*core->destroyDrawable)(private->driDrawable); /* If the X window was destroyed, the dri DestroyWindow hook will * aready have taken care of this, so only call if pDraw isn't NULL. */ if (drawable->pDraw != NULL) - DRI2DestroyDrawable(drawable->pDraw->pScreen, drawable->pDraw); + DRI2DestroyDrawable(drawable->pDraw); xfree(private); } @@ -118,25 +119,25 @@ __glXDRIdrawableResize(__GLXdrawable *glxPriv) } static GLboolean -__glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate) +__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) { - __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; + __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; + const __DRIcoreExtension *core = private->screen->core; - (*private->driDrawable.swapBuffers)(&private->driDrawable); + (*core->swapBuffers)(private->driDrawable); return TRUE; } static int -__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval) +__glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval) { - __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable; - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(baseDrawable->pDraw->pScreen); + __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; + const __DRIswapControlExtension *swapControl = private->screen->swapControl; - if (screen->swapControl) - screen->swapControl->setSwapInterval(&draw->driDrawable, interval); + if (swapControl) + swapControl->setSwapInterval(private->driDrawable, interval); return 0; } @@ -147,22 +148,20 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, int x, int y, int w, int h) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(basePrivate->pDraw->pScreen); + const __DRIcopySubBufferExtension *copySubBuffer = + private->screen->copySubBuffer; - if (screen->copySubBuffer) - screen->copySubBuffer->copySubBuffer(&private->driDrawable, - x, y, w, h); + if (copySubBuffer) + (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h); } static void __glXDRIcontextDestroy(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIscreen *screen = (__GLXDRIscreen *) baseContext->pGlxScreen; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - context->driContext.destroyContext(&context->driContext); - drmDestroyContext(screen->fd, context->hwContext); + (*screen->core->destroyContext)(context->driContext); __glXContextDestroy(&context->base); xfree(context); } @@ -173,18 +172,20 @@ __glXDRIcontextMakeCurrent(__GLXcontext *baseContext) __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } static int __glXDRIcontextLoseCurrent(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.unbindContext)(&context->driContext); + return (*screen->core->unbindContext)(context->driContext); } static int @@ -193,13 +194,10 @@ __glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, { __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; + __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; - /* FIXME: We will need to add DRIcontext::copyContext for this. */ - - (void) dst; - (void) src; - - return FALSE; + return (*screen->core->copyContext)(dst->driContext, + src->driContext, mask); } static int @@ -208,10 +206,11 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } #ifdef __DRI_TEX_BUFFER @@ -221,19 +220,16 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, int buffer, __GLXdrawable *glxPixmap) { - ScreenPtr pScreen = glxPixmap->pDraw->pScreen; - __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen); - PixmapPtr pixmap; - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; + const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer; + __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - if (screen->texBuffer == NULL) + if (texBuffer == NULL) return Success; - pixmap = (PixmapPtr) glxPixmap->pDraw; - screen->texBuffer->setTexBuffer(&context->driContext, - glxPixmap->target, - &drawable->driDrawable); + texBuffer->setTexBuffer(context->driContext, + glxPixmap->target, + drawable->driDrawable); return Success; } @@ -277,7 +273,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - screen->driScreen.destroyScreen(&screen->driScreen); + (*screen->core->destroyScreen)(screen->driScreen); dlclose(screen->driver); @@ -288,16 +284,18 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) static __GLXcontext * __glXDRIscreenCreateContext(__GLXscreen *baseScreen, - __GLcontextModes *modes, + __GLXconfig *glxConfig, __GLXcontext *baseShareContext) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; __GLXDRIcontext *context, *shareContext; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; + const __DRIcoreExtension *core = screen->core; __DRIcontext *driShare; shareContext = (__GLXDRIcontext *) baseShareContext; if (shareContext) - driShare = &shareContext->driContext; + driShare = shareContext->driContext; else driShare = NULL; @@ -313,16 +311,9 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, context->base.forceCurrent = __glXDRIcontextForceCurrent; context->base.textureFromPixmap = &__glXDRItextureFromPixmap; - if (drmCreateContext(screen->fd, &context->hwContext)) - return GL_FALSE; - - context->driContext.private = - screen->driScreen.createNewContext(&screen->driScreen, - modes, - 0, /* render type */ - driShare, - context->hwContext, - &context->driContext); + context->driContext = + (*core->createNewContext)(screen->driScreen, + config->driConfig, driShare, context); return &context->base; } @@ -332,13 +323,13 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes) + __GLXconfig *glxConfig) { __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __GLXDRIdrawable *private; GLboolean retval; - drm_drawable_t hwDrawable; - unsigned int head; + unsigned int handle, head; private = xalloc(sizeof *private); if (private == NULL) @@ -346,8 +337,9 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, memset(private, 0, sizeof *private); + private->screen = driScreen; if (!__glXDrawableInit(&private->base, screen, - pDraw, type, drawId, modes)) { + pDraw, type, drawId, glxConfig)) { xfree(private); return NULL; } @@ -357,14 +349,12 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, private->base.swapBuffers = __glXDRIdrawableSwapBuffers; private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; - retval = DRI2CreateDrawable(screen->pScreen, pDraw, - &hwDrawable, &head); + retval = DRI2CreateDrawable(pDraw, &handle, &head); - private->driDrawable.private = - (driScreen->driScreen.createNewDrawable)(&driScreen->driScreen, - modes, - &private->driDrawable, - hwDrawable, head, 0, NULL); + private->driDrawable = + (*driScreen->core->createNewDrawable)(driScreen->driScreen, + config->driConfig, + handle, head, private); return &private->base; } @@ -385,44 +375,43 @@ 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, ®ion, (BoxPtr) rects, num_rects); - REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y); - DamageDamageRegion(pDraw, ®ion); - REGION_UNINIT(pDraw->pScreen, ®ion); -} - -/* Table of functions that we export to the driver. */ -static const __DRIcontextModesExtension contextModesExtension = { - { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, - _gl_context_modes_create, - _gl_context_modes_destroy, -}; - static const __DRIsystemTimeExtension systemTimeExtension = { { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, getUST, NULL, }; -static const __DRIdamageExtension damageExtension = { - { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, - __glXReportDamage, +static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail, + void *loaderPrivate) +{ + __GLXDRIdrawable *pdraw = loaderPrivate; + + DRI2ReemitDrawableInfo(pdraw->base.pDraw, tail); +} + +static void dri2PostDamage(__DRIdrawable *draw, + struct drm_clip_rect *rects, + int numRects, void *loaderPrivate) +{ + __GLXDRIdrawable *drawable = loaderPrivate; + DrawablePtr pDraw = drawable->base.pDraw; + RegionRec region; + + REGION_INIT(pDraw->pScreen, ®ion, (BoxPtr) rects, numRects); + REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y); + DamageDamageRegion(pDraw, ®ion); + REGION_UNINIT(pDraw->pScreen, ®ion); +} + +static const __DRIloaderExtension loaderExtension = { + { __DRI_LOADER, __DRI_LOADER_VERSION }, + dri2ReemitDrawableInfo, + dri2PostDamage }; static const __DRIextension *loader_extensions[] = { - &contextModesExtension.base, &systemTimeExtension.base, - &damageExtension.base, + &loaderExtension.base, NULL }; @@ -463,11 +452,13 @@ initializeExtensions(__GLXDRIscreen *screen) const __DRIextension **extensions; int i; - extensions = screen->driScreen.getExtensions(&screen->driScreen); + extensions = screen->core->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]; + screen->copySubBuffer = + (const __DRIcopySubBufferExtension *) extensions[i]; __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); @@ -477,7 +468,8 @@ initializeExtensions(__GLXDRIscreen *screen) #ifdef __DRI_SWAP_CONTROL if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { - screen->swapControl = (__DRIswapControlExtension *) extensions[i]; + screen->swapControl = + (const __DRIswapControlExtension *) extensions[i]; __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control"); __glXEnableExtension(screen->glx_enable_bits, @@ -489,7 +481,8 @@ initializeExtensions(__GLXDRIscreen *screen) #ifdef __DRI_TEX_BUFFER if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { - screen->texBuffer = (__DRItexBufferExtension *) extensions[i]; + screen->texBuffer = + (const __DRItexBufferExtension *) extensions[i]; /* GLX_EXT_texture_from_pixmap is always enabled. */ LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); } @@ -498,27 +491,176 @@ initializeExtensions(__GLXDRIscreen *screen) } } +#define __ATTRIB(attrib, field) \ + { attrib, offsetof(__GLXconfig, field) } + +static const struct { unsigned int attrib, offset; } attribMap[] = { + __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), + __ATTRIB(__DRI_ATTRIB_LEVEL, level), + __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), + __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), + __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), + __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), + __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), + __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), + __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), + __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), + __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), + __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), + __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), + __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode), + __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), + __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), + __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), + __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), + __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), + __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +static void +setScalar(__GLXconfig *config, unsigned int attrib, unsigned int value) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(attribMap); i++) + if (attribMap[i].attrib == attrib) { + *(unsigned int *) ((char *) config + attribMap[i].offset) = value; + return; + } +} + +static __GLXconfig * +createModeFromConfig(const __DRIcoreExtension *core, + const __DRIconfig *driConfig, + unsigned int visualType) +{ + __GLXDRIconfig *config; + unsigned int attrib, value; + int i; + + config = xalloc(sizeof *config); + + config->driConfig = driConfig; + + i = 0; + while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) { + switch (attrib) { + case __DRI_ATTRIB_RENDER_TYPE: + if (value & __DRI_ATTRIB_RGBA_BIT) { + config->config.renderType |= GLX_RGBA_BIT; + config->config.rgbMode = GL_TRUE; + } else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) { + config->config.renderType |= GLX_COLOR_INDEX_BIT; + config->config.rgbMode = GL_FALSE; + } else { + config->config.renderType = 0; + config->config.rgbMode = GL_FALSE; + } + break; + case __DRI_ATTRIB_CONFIG_CAVEAT: + if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) + config->config.visualRating = GLX_NON_CONFORMANT_CONFIG; + else if (value & __DRI_ATTRIB_SLOW_BIT) + config->config.visualRating = GLX_SLOW_CONFIG; + else + config->config.visualRating = GLX_NONE; + break; + case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS: + config->config.bindToTextureTargets = 0; + if (value & __DRI_ATTRIB_TEXTURE_1D_BIT) + config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT; + if (value & __DRI_ATTRIB_TEXTURE_2D_BIT) + config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT; + if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT) + config->config.bindToTextureTargets |= GLX_TEXTURE_RECTANGLE_BIT_EXT; + break; + default: + setScalar(&config->config, attrib, value); + break; + } + } + + config->config.next = NULL; + config->config.xRenderable = GL_TRUE; + config->config.visualType = visualType; + config->config.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; + + return &config->config; +} + +__GLXconfig * +glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs); + +__GLXconfig * +glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs) +{ + __GLXconfig head, *tail; + int i; + + tail = &head; + head.next = NULL; + + for (i = 0; configs[i]; i++) { + tail->next = createModeFromConfig(core, + configs[i], GLX_TRUE_COLOR); + if (tail->next == NULL) + break; + + tail = tail->next; + } + + for (i = 0; configs[i]; i++) { + tail->next = createModeFromConfig(core, + configs[i], GLX_DIRECT_COLOR); + if (tail->next == NULL) + break; + + tail = tail->next; + } + + return head.next; +} + static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { - __DRI2_CREATE_NEW_SCREEN_FUNC *createNewScreen; const char *driverName; __GLXDRIscreen *screen; char filename[128]; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; unsigned int sareaHandle; + const __DRIextension **extensions; + const __DRIconfig **driConfigs; + int i; screen = xalloc(sizeof *screen); if (screen == NULL) - return NULL; + return NULL; memset(screen, 0, sizeof *screen); if (!xf86LoaderCheckSymbol("DRI2Connect") || - !DRI2Connect(pScreen, - &screen->fd, - &driverName, - &sareaHandle)) { + !DRI2Connect(pScreen, &screen->fd, &driverName, &sareaHandle)) { LogMessage(X_INFO, "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum); return NULL; @@ -532,8 +674,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __glXInitExtensionEnableBits(screen->glx_enable_bits); - snprintf(filename, sizeof filename, "%s/%s_dri.so", - dri_driver_path, driverName); + snprintf(filename, sizeof filename, + "%s/%s_dri.so", dri_driver_path, driverName); screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); if (screen->driver == NULL) { @@ -542,28 +684,43 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC); - if (createNewScreen == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n", - CREATE_NEW_SCREEN_FUNC, dlerror()); - goto handle_error; + extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", + driverName, dlerror()); + goto handle_error; } - screen->driScreen.private = - (*createNewScreen)(pScreen->myNum, - &screen->driScreen, - screen->fd, - sareaHandle, - loader_extensions, - &screen->base.fbconfigs); + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && + extensions[i]->version >= __DRI_CORE_VERSION) { + screen->core = (const __DRIcoreExtension *) extensions[i]; + } + } - if (screen->driScreen.private == NULL) { + if (screen->core == NULL) { + LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n", + driverName); + goto handle_error; + } + + screen->driScreen = + (*screen->core->createNewScreen)(pScreen->myNum, + screen->fd, + sareaHandle, + loader_extensions, + &driConfigs, + screen); + + if (screen->driScreen == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); goto handle_error; } initializeExtensions(screen); + screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); + __glXScreenInit(&screen->base, pScreen); buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index 0750e12822..bbfa02b792 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -46,7 +46,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include "glcontextmodes.h" #include "os.h" typedef struct __GLXMESAscreen __GLXMESAscreen; @@ -120,7 +119,7 @@ static __GLXdrawable * __glXMesaScreenCreateDrawable(__GLXscreen *screen, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes) + __GLXconfig *modes) { __GLXMESAdrawable *glxPriv; XMesaVisual xm_vis; @@ -217,7 +216,7 @@ __glXMesaContextForceCurrent(__GLXcontext *baseContext) static __GLXcontext * __glXMesaScreenCreateContext(__GLXscreen *screen, - __GLcontextModes *modes, + __GLXconfig *config, __GLXcontext *baseShareContext) { __GLXMESAcontext *context; @@ -232,7 +231,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen, memset(context, 0, sizeof *context); context->base.pGlxScreen = screen; - context->base.modes = modes; + context->base.config = config; context->base.destroy = __glXMesaContextDestroy; context->base.makeCurrent = __glXMesaContextMakeCurrent; @@ -240,10 +239,10 @@ __glXMesaScreenCreateContext(__GLXscreen *screen, context->base.copy = __glXMesaContextCopy; context->base.forceCurrent = __glXMesaContextForceCurrent; - xm_vis = find_mesa_visual(screen, modes->fbconfigID); + xm_vis = find_mesa_visual(screen, config->fbconfigID); if (!xm_vis) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", - modes->visualID); + config->visualID); xfree(context); return NULL; } @@ -282,11 +281,11 @@ static XMesaVisual find_mesa_visual(__GLXscreen *screen, XID fbconfigID) { __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen; - const __GLcontextModes *modes; + const __GLXconfig *config; unsigned i = 0; - for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) { - if (modes->fbconfigID == fbconfigID) + for (config = screen->fbconfigs; config != NULL; config = config->next) { + if (config->fbconfigID == fbconfigID) return mesaScreen->xm_vis[i]; i++; } @@ -298,18 +297,31 @@ const static int numBack = 2; const static int numDepth = 2; const static int numStencil = 2; -static __GLcontextModes * +static const int glx_visual_types[] = { + GLX_STATIC_GRAY, + GLX_GRAY_SCALE, + GLX_STATIC_COLOR, + GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, + GLX_DIRECT_COLOR +}; + +static __GLXconfig * createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, - VisualPtr visual, __GLcontextModes *config) + VisualPtr visual, __GLXconfig *tail) { int back, depth, stencil; + __GLXconfig *config; /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ for (back = numBack - 1; back >= 0; back--) for (depth = 0; depth < numDepth; depth++) for (stencil = 0; stencil < numStencil; stencil++) { - config->visualType = _gl_convert_from_x_visual_type(visual->class); + config->next = xalloc(sizeof *config); + config = config->next; + + config->visualType = glx_visual_types[visual->class]; config->xRenderable = GL_TRUE; config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; config->rgbMode = (visual->class >= TrueColor); @@ -333,35 +345,35 @@ createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, config->alphaMask = 0; config->rgbBits = config->rgbMode ? visual->nplanes : 0; config->indexBits = config->colorIndexMode ? visual->nplanes : 0; - config = config->next; } - return config; + return tail; } static void createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen) { - __GLcontextModes *configs; + __GLXconfig head, *tail; int i; /* We assume here that each existing visual correspond to a * different visual class. Note, this runs before COMPOSITE adds * its visual, so it's not entirely crazy. */ pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil; - pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs, - sizeof *configs); - - configs = pGlxScreen->fbconfigs; + + head.next = NULL; + tail = &head; for (i = 0; i < pScreen->numVisuals; i++) - configs = createFBConfigsForVisual(pGlxScreen, pScreen, - &pScreen->visuals[i], configs); + tail = createFBConfigsForVisual(pGlxScreen, pScreen, + &pScreen->visuals[i], tail); + + pGlxScreen->fbconfigs = head.next; } static void createMesaVisuals(__GLXMESAscreen *pMesaScreen) { - __GLcontextModes *config; + __GLXconfig *config; ScreenPtr pScreen; VisualPtr visual = NULL; int i, j; diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 6575b271d6..b49a775b50 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -37,6 +37,7 @@ #include #endif +#include #include #include #include @@ -46,7 +47,6 @@ #include "glxserver.h" #include "glxutil.h" #include "glxext.h" -#include "glcontextmodes.h" static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKey; @@ -280,10 +280,23 @@ void GlxSetVisualConfigs(int nconfigs, * call it. */ } +GLint glxConvertToXVisualType(int visualType) +{ + static const int x_visual_types[] = { + TrueColor, DirectColor, + PseudoColor, StaticColor, + GrayScale, StaticGray + }; + + return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 ) + ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; +} + + static void filterOutNativeConfigs(__GLXscreen *pGlxScreen) { - __GLcontextModes *m, *next, *native_modes, **last; + __GLXconfig *m, *next, **last; ScreenPtr pScreen = pGlxScreen->pScreen; int i, depth; @@ -305,12 +318,12 @@ filterOutNativeConfigs(__GLXscreen *pGlxScreen) } static XID -findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m) +findVisualForConfig(ScreenPtr pScreen, __GLXconfig *m) { int i; for (i = 0; i < pScreen->numVisuals; i++) { - if (_gl_convert_to_x_visual_type(m->visualType) == pScreen->visuals[i].class) + if (glxConvertToXVisualType(m->visualType) == pScreen->visuals[i].class) return pScreen->visuals[i].vid; } @@ -405,10 +418,10 @@ findFirstSet(unsigned int v) } static void -initGlxVisual(VisualPtr visual, __GLcontextModes *config) +initGlxVisual(VisualPtr visual, __GLXconfig *config) { config->visualID = visual->vid; - visual->class = _gl_convert_to_x_visual_type(config->visualType); + visual->class = glxConvertToXVisualType(config->visualType); visual->bitsPerRGBValue = config->redBits; visual->ColormapEntries = 1 << config->redBits; visual->nplanes = config->redBits + config->greenBits + config->blueBits; @@ -426,15 +439,15 @@ typedef struct { GLboolean depthBuffer; } FBConfigTemplateRec, *FBConfigTemplatePtr; -static __GLcontextModes * +static __GLXconfig * pickFBConfig(__GLXscreen *pGlxScreen, FBConfigTemplatePtr template, int class) { - __GLcontextModes *config; + __GLXconfig *config; for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { if (config->visualRating != GLX_NONE) continue; - if (_gl_convert_to_x_visual_type(config->visualType) != class) + if (glxConvertToXVisualType(config->visualType) != class) continue; if ((config->doubleBufferMode > 0) != template->doubleBuffer) continue; @@ -450,32 +463,36 @@ pickFBConfig(__GLXscreen *pGlxScreen, FBConfigTemplatePtr template, int class) static void addMinimalSet(__GLXscreen *pGlxScreen) { - __GLcontextModes *config; + __GLXconfig *config; VisualPtr visuals; - int i; + int i, j; FBConfigTemplateRec best = { GL_TRUE, GL_TRUE }; FBConfigTemplateRec minimal = { GL_FALSE, GL_FALSE }; pGlxScreen->visuals = xcalloc(pGlxScreen->pScreen->numVisuals, - sizeof (__GLcontextModes *)); + sizeof (__GLXconfig *)); if (pGlxScreen->visuals == NULL) { ErrorF("Failed to allocate for minimal set of GLX visuals\n"); return; } - pGlxScreen->numVisuals = pGlxScreen->pScreen->numVisuals; visuals = pGlxScreen->pScreen->visuals; - for (i = 0; i < pGlxScreen->numVisuals; i++) { + for (i = 0, j = 0; i < pGlxScreen->pScreen->numVisuals; i++) { if (visuals[i].nplanes == 32) config = pickFBConfig(pGlxScreen, &minimal, visuals[i].class); else config = pickFBConfig(pGlxScreen, &best, visuals[i].class); if (config == NULL) config = pGlxScreen->fbconfigs; - pGlxScreen->visuals[i] = config; - config->visualID = visuals[i].vid; + if (config == NULL) + continue; + + pGlxScreen->visuals[j] = config; + config->visualID = visuals[j].vid; + j++; } + pGlxScreen->numVisuals = j; } static void @@ -487,12 +504,12 @@ addTypicalSet(__GLXscreen *pGlxScreen) static void addFullSet(__GLXscreen *pGlxScreen) { - __GLcontextModes *config; + __GLXconfig *config; VisualPtr visuals; int i, depth; pGlxScreen->visuals = - xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLcontextModes *)); + xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *)); if (pGlxScreen->visuals == NULL) { ErrorF("Failed to allocate for full set of GLX visuals\n"); return; @@ -522,7 +539,7 @@ void GlxSetVisualConfig(int config) void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) { - __GLcontextModes *m; + __GLXconfig *m; int i; pGlxScreen->pScreen = pScreen; diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h index f1eef912ce..39d162d760 100644 --- a/GL/glx/glxscreens.h +++ b/GL/glx/glxscreens.h @@ -40,8 +40,6 @@ ** */ -#include "GL/internal/glcore.h" - typedef struct { void * (* queryHyperpipeNetworkFunc)(int, int *, int *); void * (* queryHyperpipeConfigFunc)(int, int, int *, int *); @@ -57,6 +55,84 @@ typedef struct { void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs); void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs); +typedef struct __GLXconfig __GLXconfig; +struct __GLXconfig { + __GLXconfig *next; + GLboolean rgbMode; + GLboolean floatMode; + GLboolean colorIndexMode; + GLuint doubleBufferMode; + GLuint stereoMode; + + GLboolean haveAccumBuffer; + GLboolean haveDepthBuffer; + GLboolean haveStencilBuffer; + + GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ + GLuint redMask, greenMask, blueMask, alphaMask; + GLint rgbBits; /* total bits for rgb */ + GLint indexBits; /* total bits for colorindex */ + + GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; + GLint depthBits; + GLint stencilBits; + + GLint numAuxBuffers; + + GLint level; + + GLint pixmapMode; + + /* GLX */ + GLint visualID; + GLint visualType; /**< One of the GLX X visual types. (i.e., + * \c GLX_TRUE_COLOR, etc.) + */ + + /* EXT_visual_rating / GLX 1.2 */ + GLint visualRating; + + /* EXT_visual_info / GLX 1.2 */ + GLint transparentPixel; + /* colors are floats scaled to ints */ + GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; + GLint transparentIndex; + + /* ARB_multisample / SGIS_multisample */ + GLint sampleBuffers; + GLint samples; + + /* SGIX_fbconfig / GLX 1.3 */ + GLint drawableType; + GLint renderType; + GLint xRenderable; + GLint fbconfigID; + + /* SGIX_pbuffer / GLX 1.3 */ + GLint maxPbufferWidth; + GLint maxPbufferHeight; + GLint maxPbufferPixels; + GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ + GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ + + /* SGIX_visual_select_group */ + GLint visualSelectGroup; + + /* OML_swap_method */ + GLint swapMethod; + + GLint screen; + + /* EXT_texture_from_pixmap */ + GLint bindToTextureRgb; + GLint bindToTextureRgba; + GLint bindToMipmapTexture; + GLint bindToTextureTargets; + GLint yInverted; +}; + +GLint glxConvertToXVisualType(int visualType); + /* ** Screen dependent data. These methods are the interface between the DIX ** and DDX layers of the GLX server extension. The methods provide an @@ -67,14 +143,14 @@ struct __GLXscreen { void (*destroy) (__GLXscreen *screen); __GLXcontext *(*createContext) (__GLXscreen *screen, - __GLcontextModes *modes, + __GLXconfig *modes, __GLXcontext *shareContext); __GLXdrawable *(*createDrawable)(__GLXscreen *context, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes); + __GLXconfig *modes); int (*swapInterval) (__GLXdrawable *drawable, int interval); @@ -84,11 +160,11 @@ struct __GLXscreen { ScreenPtr pScreen; /* Linked list of valid fbconfigs for this screen. */ - __GLcontextModes *fbconfigs; + __GLXconfig *fbconfigs; int numFBConfigs; /* Subset of fbconfigs that are exposed as GLX visuals. */ - __GLcontextModes **visuals; + __GLXconfig **visuals; GLint numVisuals; char *GLextensions; diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c index f531ed954b..11e9f898b7 100644 --- a/GL/glx/glxutil.c +++ b/GL/glx/glxutil.c @@ -49,7 +49,6 @@ #include "glxutil.h" #include "GL/internal/glcore.h" #include "GL/glxint.h" -#include "glcontextmodes.h" /************************************************************************/ /* Context stuff */ @@ -140,13 +139,13 @@ __glXUnrefDrawable(__GLXdrawable *glxPriv) GLboolean __glXDrawableInit(__GLXdrawable *drawable, __GLXscreen *screen, DrawablePtr pDraw, int type, - XID drawId, __GLcontextModes *modes) + XID drawId, __GLXconfig *config) { drawable->pDraw = pDraw; drawable->type = type; drawable->drawId = drawId; drawable->refCount = 1; - drawable->modes = modes; + drawable->config = config; drawable->eventMask = 0; return GL_TRUE; diff --git a/GL/glx/glxutil.h b/GL/glx/glxutil.h index 6534c3f94e..00c7b2084a 100644 --- a/GL/glx/glxutil.h +++ b/GL/glx/glxutil.h @@ -51,7 +51,7 @@ extern void __glXUnrefDrawable(__GLXdrawable *glxPriv); extern GLboolean __glXDrawableInit(__GLXdrawable *drawable, __GLXscreen *screen, DrawablePtr pDraw, int type, XID drawID, - __GLcontextModes *modes); + __GLXconfig *config); /* context helper routines */ extern __GLXcontext *__glXLookupContextByTag(__GLXclientState*, GLXContextTag); diff --git a/GL/symlink-mesa.sh b/GL/symlink-mesa.sh index af9adbd940..47afdcd371 100755 --- a/GL/symlink-mesa.sh +++ b/GL/symlink-mesa.sh @@ -227,8 +227,6 @@ symlink_glx() { dst_dir glx action indirect_size.h - action glcontextmodes.c - action glcontextmodes.h action indirect_dispatch.c action indirect_dispatch.h action indirect_dispatch_swap.c diff --git a/configure.ac b/configure.ac index 959f0aedf5..e72e3b99a3 100644 --- a/configure.ac +++ b/configure.ac @@ -860,7 +860,7 @@ AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) if test "x$DRI2" = xyes; then # FIXME: Bump the versions once we have releases of these. AC_DEFINE(DRI2, 1, [Build DRI2 extension]) - PKG_CHECK_MODULES([DRIPROTO], [xf86driproto >= 2.0.3]) + PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.0.0]) PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.3.1]) fi diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 4a4aabcb59..8de7426207 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -121,6 +121,7 @@ static ModuleDefault ModuleDefaults[] = { {.name = "freetype", .toLoad = TRUE, .load_opt=NULL}, {.name = "record", .toLoad = TRUE, .load_opt=NULL}, {.name = "dri", .toLoad = TRUE, .load_opt=NULL}, + {.name = "dri2", .toLoad = TRUE, .load_opt=NULL}, {.name = NULL, .toLoad = FALSE, .load_opt=NULL} }; diff --git a/hw/xfree86/dri2/Makefile.am b/hw/xfree86/dri2/Makefile.am index be3cea48fe..844c912401 100644 --- a/hw/xfree86/dri2/Makefile.am +++ b/hw/xfree86/dri2/Makefile.am @@ -2,7 +2,7 @@ libdri2_la_LTLIBRARIES = libdri2.la libdri2_la_CFLAGS = \ -DHAVE_XORG_CONFIG_H \ -I@MESA_SOURCE@/include \ - @DIX_CFLAGS@ @DRIPROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ + @DIX_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/os-support/bus @@ -10,6 +10,7 @@ libdri2_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ libdri2_ladir = $(moduledir)/extensions libdri2_la_SOURCES = \ dri2.c \ - dri2.h + dri2.h \ + dri2ext.c sdk_HEADERS = dri2.h diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index d5273877e1..74aef7196b 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -38,6 +38,8 @@ #include "xf86Module.h" #include "scrnintstr.h" #include "windowstr.h" +#include "region.h" +#include "damage.h" #include "dri2.h" #include @@ -48,8 +50,9 @@ static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKey; static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKey; typedef struct _DRI2DrawablePriv { - drm_drawable_t drawable; - unsigned int handle; + unsigned int refCount; + unsigned int boHandle; + unsigned int dri2Handle; } DRI2DrawablePrivRec, *DRI2DrawablePrivPtr; typedef struct _DRI2Screen { @@ -58,6 +61,7 @@ typedef struct _DRI2Screen { void *sarea; unsigned int sareaSize; const char *driverName; + unsigned int nextHandle; __DRIEventBuffer *buffer; int locked; @@ -147,7 +151,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw) e = DRI2ScreenAllocEvent(ds, size); e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_DRAWABLE_CONFIG, size); - e->drawable = pPriv->drawable; + e->drawable = pPriv->dri2Handle; e->x = pDraw->x - pPixmap->screen_x; e->y = pDraw->y - pPixmap->screen_y; e->width = pDraw->width; @@ -164,7 +168,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw) } static void -DRI2PostBufferAttach(DrawablePtr pDraw) +DRI2PostBufferAttach(DrawablePtr pDraw, Bool force) { ScreenPtr pScreen = pDraw->pScreen; DRI2ScreenPtr ds = DRI2GetScreen(pScreen); @@ -173,7 +177,8 @@ DRI2PostBufferAttach(DrawablePtr pDraw) PixmapPtr pPixmap; __DRIBufferAttachEvent *e; size_t size; - unsigned int handle, flags; + unsigned int flags; + unsigned int boHandle; if (pDraw->type == DRAWABLE_WINDOW) { pWin = (WindowPtr) pDraw; @@ -187,22 +192,20 @@ DRI2PostBufferAttach(DrawablePtr pDraw) if (!pPriv) return; - size = sizeof *e; - - handle = ds->getPixmapHandle(pPixmap, &flags); - if (handle == 0 || handle == pPriv->handle) + boHandle = ds->getPixmapHandle(pPixmap, &flags); + if (boHandle == pPriv->boHandle && !force) return; + pPriv->boHandle = boHandle; + size = sizeof *e; e = DRI2ScreenAllocEvent(ds, size); e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_BUFFER_ATTACH, size); - e->drawable = pPriv->drawable; + e->drawable = pPriv->dri2Handle; e->buffer.attachment = DRI_DRAWABLE_BUFFER_FRONT_LEFT; - e->buffer.handle = handle; + e->buffer.handle = pPriv->boHandle; e->buffer.pitch = pPixmap->devKind; e->buffer.cpp = pPixmap->drawable.bitsPerPixel / 8; e->buffer.flags = flags; - - pPriv->handle = handle; } static void @@ -223,7 +226,7 @@ DRI2ClipNotify(WindowPtr pWin, int dx, int dy) } DRI2PostDrawableConfig(&pWin->drawable); - DRI2PostBufferAttach(&pWin->drawable); + DRI2PostBufferAttach(&pWin->drawable, FALSE); } static void @@ -262,10 +265,10 @@ DRI2CloseScreen(ScreenPtr pScreen) } Bool -DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw, - drm_drawable_t *pDrmDrawable, unsigned int *head) +DRI2CreateDrawable(DrawablePtr pDraw, + unsigned int *handle, unsigned int *head) { - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); WindowPtr pWin; PixmapPtr pPixmap; DRI2DrawablePrivPtr pPriv; @@ -283,47 +286,66 @@ DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw, } pPriv = dixLookupPrivate(devPrivates, key); - if (pPriv == NULL) { + if (pPriv != NULL) { + pPriv->refCount++; + } else { pPriv = xalloc(sizeof *pPriv); - if (drmCreateDrawable(ds->fd, &pPriv->drawable)) - return FALSE; - + pPriv->refCount = 1; + pPriv->boHandle = 0; + pPriv->dri2Handle = ds->nextHandle++; dixSetPrivate(devPrivates, key, pPriv); } - *pDrmDrawable = pPriv->drawable; - + *handle = pPriv->dri2Handle; *head = ds->buffer->head; + DRI2PostDrawableConfig(pDraw); - DRI2PostBufferAttach(pDraw); + DRI2PostBufferAttach(pDraw, TRUE); DRI2ScreenCommitEvents(ds); return TRUE; } void -DRI2DestroyDrawable(ScreenPtr pScreen, DrawablePtr pDraw) +DRI2DestroyDrawable(DrawablePtr pDraw) { - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); - PixmapPtr pPixmap; - WindowPtr pWin; - DRI2DrawablePrivPtr pPriv; + PixmapPtr pPixmap; + WindowPtr pWin; + DRI2DrawablePrivPtr pPriv; + DevPrivateKey key; + PrivateRec **devPrivates; if (pDraw->type == DRAWABLE_WINDOW) { pWin = (WindowPtr) pDraw; - pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey); - dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL); + devPrivates = &pWin->devPrivates; + key = dri2WindowPrivateKey; } else { pPixmap = (PixmapPtr) pDraw; - pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey); - dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL); + devPrivates = &pPixmap->devPrivates; + key = dri2PixmapPrivateKey; } + pPriv = dixLookupPrivate(devPrivates, key); if (pPriv == NULL) return; - drmDestroyDrawable(ds->fd, pPriv->drawable); - xfree(pPriv); + pPriv->refCount--; + if (pPriv->refCount == 0) { + dixSetPrivate(devPrivates, key, NULL); + xfree(pPriv); + } +} + +void +DRI2ReemitDrawableInfo(DrawablePtr pDraw, unsigned int *head) +{ + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + + *head = ds->buffer->head; + + DRI2PostDrawableConfig(pDraw); + DRI2PostBufferAttach(pDraw, TRUE); + DRI2ScreenCommitEvents(ds); } Bool @@ -409,8 +431,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) if (!ds) return NULL; - ds->fd = info->fd; + ds->fd = info->fd; ds->driverName = info->driverName; + ds->nextHandle = 1; ds->getPixmapHandle = info->getPixmapHandle; ds->beginClipNotify = info->beginClipNotify; @@ -434,9 +457,21 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) return p; } +extern ExtensionModule dri2ExtensionModule; + static pointer DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin) { + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + LoadExtension(&dri2ExtensionModule, FALSE); + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + } + return (pointer) 1; } diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 126087a2f3..85b3da41c9 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -66,14 +66,16 @@ unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap, void DRI2Lock(ScreenPtr pScreen); void DRI2Unlock(ScreenPtr pScreen); -Bool DRI2CreateDrawable(ScreenPtr pScreen, - DrawablePtr pDraw, - drm_drawable_t *pDrmDrawable, - unsigned int *head); +Bool DRI2CreateDrawable(DrawablePtr pDraw, + unsigned int *handle, + unsigned int *head); -void DRI2DestroyDrawable(ScreenPtr pScreen, - DrawablePtr pDraw); +void DRI2DestroyDrawable(DrawablePtr pDraw); -void DRI2ExtensionInit(void); +void DRI2ReemitDrawableInfo(DrawablePtr pDraw, + unsigned int *head); + +Bool DRI2PostDamage(DrawablePtr pDrawable, + struct drm_clip_rect *rects, int numRects); #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c new file mode 100644 index 0000000000..ca2e029707 --- /dev/null +++ b/hw/xfree86/dri2/dri2ext.c @@ -0,0 +1,361 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL 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 PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#define NEED_REPLIES +#include +#include +#include "dixstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "extnsionst.h" +#include "xf86drm.h" +#include "dri2proto.h" +#include "dri2.h" + +/* The only xf86 include */ +#include "xf86Module.h" + +static ExtensionEntry *dri2Extension; +static RESTYPE dri2DrawableRes; + +static Bool +validScreen(ClientPtr client, int screen, ScreenPtr *pScreen) +{ + if (screen >= screenInfo.numScreens) { + client->errorValue = screen; + return FALSE; + } + + *pScreen = screenInfo.screens[screen]; + + return TRUE; +} + +static Bool +validDrawable(ClientPtr client, XID drawable, + DrawablePtr *pDrawable, int *status) +{ + *status = dixLookupDrawable(pDrawable, drawable, client, 0, DixReadAccess); + if (*status != Success) { + client->errorValue = drawable; + return FALSE; + } + + return TRUE; +} + +static int +ProcDRI2QueryVersion(ClientPtr client) +{ + REQUEST(xDRI2QueryVersionReq); + xDRI2QueryVersionReply rep; + int n; + + if (client->swapped) + swaps(&stuff->length, n); + + REQUEST_SIZE_MATCH(xDRI2QueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = DRI2_MAJOR; + rep.minorVersion = DRI2_MINOR; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + + WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + ScreenPtr pScreen; + int fd; + const char *driverName; + char *busId; + unsigned int sareaHandle; + + REQUEST_SIZE_MATCH(xDRI2ConnectReq); + if (!validScreen(client, stuff->screen, &pScreen)) + return BadValue; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.driverNameLength = 0; + rep.busIdLength = 0; + rep.sareaHandle = 0; + + if (!DRI2Connect(pScreen, &fd, &driverName, &sareaHandle)) + goto fail; + + busId = drmGetBusid(fd); + if (busId == NULL) + goto fail; + + rep.driverNameLength = strlen(driverName); + rep.busIdLength = strlen(busId); + rep.sareaHandle = sareaHandle; + rep.length = (rep.driverNameLength + 3) / 4 + (rep.busIdLength + 3) / 4; + + fail: + WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); + WriteToClient(client, rep.driverNameLength, driverName); + WriteToClient(client, rep.busIdLength, busId); + drmFreeBusid(busId); + + return client->noClientException; +} + +static int +ProcDRI2AuthConnection(ClientPtr client) +{ + REQUEST(xDRI2AuthConnectionReq); + xDRI2AuthConnectionReply rep; + ScreenPtr pScreen; + + REQUEST_SIZE_MATCH(xDRI2AuthConnectionReq); + if (!validScreen(client, stuff->screen, &pScreen)) + return BadValue; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.authenticated = 1; + + if (!DRI2AuthConnection(pScreen, stuff->magic)) { + ErrorF("DRI2: Failed to authenticate %lu\n", + (unsigned long) stuff->magic); + rep.authenticated = 0; + } + + WriteToClient(client, sizeof(xDRI2AuthConnectionReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2CreateDrawable(ClientPtr client) +{ + REQUEST(xDRI2CreateDrawableReq); + xDRI2CreateDrawableReply rep; + DrawablePtr pDrawable; + unsigned int handle, head; + int status; + + REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); + + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + if (!DRI2CreateDrawable(pDrawable, &handle, &head)) + return BadMatch; + + if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) { + DRI2DestroyDrawable(pDrawable); + return BadAlloc; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.handle = handle; + rep.head = head; + + WriteToClient(client, sizeof(xDRI2CreateDrawableReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2DestroyDrawable(ClientPtr client) +{ + REQUEST(xDRI2DestroyDrawableReq); + DrawablePtr pDrawable; + int status; + + REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE); + + return client->noClientException; +} + +static int +ProcDRI2ReemitDrawableInfo(ClientPtr client) +{ + REQUEST(xDRI2ReemitDrawableInfoReq); + xDRI2ReemitDrawableInfoReply rep; + DrawablePtr pDrawable; + unsigned int head; + int status; + + REQUEST_SIZE_MATCH(xDRI2ReemitDrawableInfoReq); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + DRI2ReemitDrawableInfo(pDrawable, &head); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.head = head; + + WriteToClient(client, sizeof(xDRI2ReemitDrawableInfoReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + } + + if (!LocalClient(client)) + return BadRequest; + + switch (stuff->data) { + case X_DRI2Connect: + return ProcDRI2Connect(client); + case X_DRI2AuthConnection: + return ProcDRI2AuthConnection(client); + case X_DRI2CreateDrawable: + return ProcDRI2CreateDrawable(client); + case X_DRI2DestroyDrawable: + return ProcDRI2DestroyDrawable(client); + case X_DRI2ReemitDrawableInfo: + return ProcDRI2ReemitDrawableInfo(client); + default: + return BadRequest; + } +} + +static int +SProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + int n; + + /* If the client is swapped, it's not local. Talk to the hand. */ + + swaps(&stuff->length, n); + if (sizeof(*stuff) / 4 != client->req_len) + return BadLength; + + rep.sequenceNumber = client->sequence; + swaps(&rep.sequenceNumber, n); + rep.length = 0; + rep.driverNameLength = 0; + rep.busIdLength = 0; + rep.sareaHandle = 0; + + return client->noClientException; +} + +static int +SProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + /* + * Only local clients are allowed DRI access, but remote clients + * still need these requests to find out cleanly. + */ + switch (stuff->data) + { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + case X_DRI2Connect: + return SProcDRI2Connect(client); + default: + return BadRequest; + } +} + +static void +DRI2ResetProc (ExtensionEntry *extEntry) +{ +} + +static int DRI2DrawableGone(pointer p, XID id) +{ + DrawablePtr pDrawable = p; + + DRI2DestroyDrawable(pDrawable); + + return Success; +} + +static void +DRI2ExtensionInit(void) +{ + dri2Extension = AddExtension(DRI2_NAME, + DRI2NumberEvents, + DRI2NumberErrors, + ProcDRI2Dispatch, + SProcDRI2Dispatch, + DRI2ResetProc, + StandardMinorOpcode); + + dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone); +} + +extern Bool noDRI2Extension; + +_X_HIDDEN ExtensionModule dri2ExtensionModule = { + DRI2ExtensionInit, + DRI2_NAME, + &noDRI2Extension, + NULL, + NULL +}; diff --git a/os/utils.c b/os/utils.c index 57293ab6ff..d785d46d2b 100644 --- a/os/utils.c +++ b/os/utils.c @@ -239,6 +239,9 @@ _X_EXPORT int selinuxEnforcingState = SELINUX_MODE_DEFAULT; #ifdef XV _X_EXPORT Bool noXvExtension = FALSE; #endif +#ifdef DRI2 +_X_EXPORT Bool noDRI2Extension = FALSE; +#endif #define X_INCLUDE_NETDB_H #include From 9f56fc580646a519875b5a1452738d8c6e1fa860 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Mon, 31 Mar 2008 17:34:07 -0400 Subject: [PATCH 02/34] XSELinux: Add a request to get a client's context from a resource ID. --- Xext/xselinux.c | 33 +++++++++++++++++++++++++++++++++ Xext/xselinux.h | 1 + 2 files changed, 34 insertions(+) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 2e059a4c3c..1e3b4d66ce 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -1472,6 +1472,24 @@ ProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey) return SELinuxSendContextReply(client, obj->sid); } +static int +ProcSELinuxGetClientContext(ClientPtr client) +{ + ClientPtr target; + SELinuxSubjectRec *subj; + int rc; + + REQUEST(SELinuxGetContextReq); + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + + rc = dixLookupClient(&target, stuff->id, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + subj = dixLookupPrivate(&target->devPrivates, subjectKey); + return SELinuxSendContextReply(client, subj->sid); +} + static int SELinuxPopulateItem(SELinuxListItemRec *i, PrivateRec **privPtr, CARD32 id, int *size) @@ -1686,6 +1704,8 @@ ProcSELinuxDispatch(ClientPtr client) return ProcSELinuxGetSelectionContext(client, dataKey); case X_SELinuxListSelections: return ProcSELinuxListSelections(client); + case X_SELinuxGetClientContext: + return ProcSELinuxGetClientContext(client); default: return BadRequest; } @@ -1782,6 +1802,17 @@ SProcSELinuxListProperties(ClientPtr client) return ProcSELinuxListProperties(client); } +static int +SProcSELinuxGetClientContext(ClientPtr client) +{ + REQUEST(SELinuxGetContextReq); + int n; + + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + swapl(&stuff->id, n); + return ProcSELinuxGetClientContext(client); +} + static int SProcSELinuxDispatch(ClientPtr client) { @@ -1835,6 +1866,8 @@ SProcSELinuxDispatch(ClientPtr client) return SProcSELinuxGetSelectionContext(client, dataKey); case X_SELinuxListSelections: return ProcSELinuxListSelections(client); + case X_SELinuxGetClientContext: + return SProcSELinuxGetClientContext(client); default: return BadRequest; } diff --git a/Xext/xselinux.h b/Xext/xselinux.h index 2d0de32226..7c3ffdcb72 100644 --- a/Xext/xselinux.h +++ b/Xext/xselinux.h @@ -52,6 +52,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define X_SELinuxGetSelectionContext 19 #define X_SELinuxGetSelectionDataContext 20 #define X_SELinuxListSelections 21 +#define X_SELinuxGetClientContext 22 typedef struct { CARD8 reqType; From 19ff23ab0e72a27d05ed4470f75a0934d6f6c1d1 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Fri, 28 Mar 2008 18:25:03 -0700 Subject: [PATCH 03/34] Remove calls to InitValuatorAxisStruct -- these are now handled in dix by InitValuatorDeviceClass. Add InitProximityClassDeviceStruct call to prepare for tablet support. (cherry picked from commit 1bd980a5b114f5320360943214f8f9f23b29c1e3) --- hw/xquartz/darwin.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 0dbfafefaa..8f2511dbb8 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -353,24 +353,8 @@ static int DarwinMouseProc( InitPointerDeviceStruct( (DevicePtr)pPointer, map, 5, GetMotionHistory, (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), 2); - -#ifdef XINPUT - InitValuatorAxisStruct( pPointer, - 0, // X axis - 0, // min value - 16000, // max value (fixme screen size?) - 1, // resolution (fixme ?) - 1, // min resolution - 1 ); // max resolution - InitValuatorAxisStruct( pPointer, - 1, // X axis - 0, // min value - 16000, // max value (fixme screen size?) - 1, // resolution (fixme ?) - 1, // min resolution - 1 ); // max resolution -#endif + GetMotionHistorySize(), 5); + InitProximityClassDeviceStruct( (DevicePtr)pPointer); break; case DEVICE_ON: From 6648867d8bd1e86458d2ade77a3ee4567c3d6a97 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Fri, 28 Mar 2008 18:27:02 -0700 Subject: [PATCH 04/34] add debug statements so we can see if/when our Xinput stubs are getting called. (cherry picked from commit 6e160bbe15dd2c2b8685847c06831cb6aebc6f74) --- hw/xquartz/darwinXinput.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c index 50ba656f8c..59bae6fde0 100644 --- a/hw/xquartz/darwinXinput.c +++ b/hw/xquartz/darwinXinput.c @@ -62,6 +62,7 @@ SOFTWARE. #include #include #include "XIstubs.h" +#include "darwin.h" /*********************************************************************** * @@ -79,6 +80,7 @@ SOFTWARE. void CloseInputDevice(DeviceIntPtr d, ClientPtr client) { + DEBUG_LOG("CloseInputDevice(%p, %p)\n", d, client); } /*********************************************************************** @@ -122,7 +124,7 @@ AddOtherInputDevices(void) RegisterOtherDevice(dev); dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); ************************************************************************/ - + DEBUG_LOG("AddOtherInputDevices\n"); } /*********************************************************************** @@ -150,6 +152,7 @@ AddOtherInputDevices(void) void OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status) { + DEBUG_LOG("OpenInputDevice(%p, %p, %p)\n", dev, client, status); } /**************************************************************************** @@ -167,6 +170,7 @@ OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status) int SetDeviceMode(ClientPtr client, DeviceIntPtr dev, int mode) { + DEBUG_LOG("SetDeviceMode(%p, %p, %d)\n", client, dev, mode); return BadMatch; } @@ -186,7 +190,9 @@ int SetDeviceValuators(ClientPtr client, DeviceIntPtr dev, int *valuators, int first_valuator, int num_valuators) { - return BadMatch; + DEBUG_LOG("SetDeviceValuators(%p, %p, %p, %d, %d)\n", client, + dev, valuators, first_valuator, num_valuators); + return BadMatch; } /**************************************************************************** @@ -201,6 +207,8 @@ int ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, xDeviceCtl * control) { + + DEBUG_LOG("ChangeDeviceControl(%p, %p, %p)\n", client, dev, control); switch (control->control) { case DEVICE_RESOLUTION: return (BadMatch); @@ -225,7 +233,8 @@ ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, int NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) { - return BadValue; + DEBUG_LOG("NewInputDeviceRequest(%p, %p)\n", options, pdev); + return BadValue; } /**************************************************************************** @@ -238,4 +247,5 @@ NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) void DeleteInputDeviceRequest(DeviceIntPtr dev) { + DEBUG_LOG("DeleteInputDeviceRequest(%p)\n", dev); } From a4d034941100c6ca3b7cc4e59952c2745b9306cc Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Fri, 28 Mar 2008 20:47:44 -0700 Subject: [PATCH 05/34] Add code to track 5 valuators for pointing device, in preparation for supporting tablet input in Xquartz. (cherry picked from commit 22c8849ea819eb70a14b2e06330b11b22aa63ebc) --- hw/xquartz/X11Application.m | 28 ++++++++++++---- hw/xquartz/darwinEvents.c | 64 ++++++++++++++++++++++++++++++------- hw/xquartz/darwinEvents.h | 8 +++-- 3 files changed, 80 insertions(+), 20 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 31c80dfa81..147b4b4c0e 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -61,7 +61,7 @@ int X11EnableKeyEquivalents = TRUE; int quartzHasRoot = FALSE, quartzEnableRootless = TRUE; extern int darwinFakeButtons, input_check_flag; -extern Bool enable_stereo; +extern Bool enable_stereo; extern xEvent *darwinEvents; @@ -153,7 +153,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { tem = [infoDict objectForKey:@"CFBundleShortVersionString"]; - [dict setObject:[NSString stringWithFormat:@"Xquartz %@ - (xorg-server %s)", tem, XSERVER_VERSION] + [dict setObject:[NSString stringWithFormat:@"XQuartz %@ - (xorg-server %s)", tem, XSERVER_VERSION] forKey:@"ApplicationVersion"]; [self orderFrontStandardAboutPanelWithOptions: dict]; @@ -501,7 +501,7 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { if (value != NULL && CFGetTypeID (value) == CFNumberGetTypeID () - && CFNumberIsFloatType (value)) + && CFNumberIsFloatType (value)) CFNumberGetValue (value, kCFNumberFloatType, &ret); else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) ret = CFStringGetDoubleValue (value); @@ -862,7 +862,9 @@ static void send_nsevent (NSEventType type, NSEvent *e) { NSRect screen; NSPoint location; NSWindow *window; - int pointer_x, pointer_y, ev_button, ev_type; + int pointer_x, pointer_y, ev_button, ev_type; + float pressure, tilt_x, tilt_y; + // int num_events=0, i=0, state; // xEvent xe; @@ -884,6 +886,10 @@ static void send_nsevent (NSEventType type, NSEvent *e) { pointer_y -= aquaMenuBarHeight; // state = convert_flags ([e modifierFlags]); + pressure = 0; // for tablets + tilt_x = 0; + tilt_y = 0; + switch (type) { case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse; case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse; @@ -894,6 +900,10 @@ static void send_nsevent (NSEventType type, NSEvent *e) { case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse; + case NSTabletPoint: + pressure = [e pressure]; + tilt_x = [e tilt].x; + tilt_y = [e tilt].y; // fall through case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse; handle_mouse: @@ -907,10 +917,14 @@ static void send_nsevent (NSEventType type, NSEvent *e) { DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y); } else if (ev_type==ButtonRelease && (button_state & (1 << ev_button)) == 0) break; */ - DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y); + + // if ([e subtype] == NSTabletPointEventSubtype) pressure = [e pressure]; + DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); break; - case NSScrollWheel: - DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y); + case NSScrollWheel: + DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y, + pressure, tilt_x, tilt_y); break; case NSKeyDown: // do we need to translate these keyCodes? diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 113cfc1091..2a28b1a31c 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -173,6 +173,9 @@ static void DarwinReleaseModifiers(void) { static void DarwinSimulateMouseClick( int pointer_x, int pointer_y, + float pressure, + float tilt_x, + float tilt_y, int whichButton, // mouse button to be pressed int modifierMask) // modifiers used for the fake click { @@ -183,8 +186,10 @@ static void DarwinSimulateMouseClick( DarwinUpdateModifiers(KeyRelease, modifierMask); // push the mouse button - DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y); - DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y); + DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); + DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); // restore old modifiers DarwinUpdateModifiers(KeyPress, modifierMask); @@ -378,22 +383,39 @@ void DarwinPokeEQ(void) { write(darwinEventWriteFD, &nullbyte, 1); } -void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y) { +void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y, + float pressure, float tilt_x, float tilt_y) { static int darwinFakeMouseButtonDown = 0; static int darwinFakeMouseButtonMask = 0; int i, num_events; - int valuators[2] = {pointer_x, pointer_y}; + + /* I can't find a spec for this, but at least GTK expects that tablets are + just like mice, except they have either one or three extra valuators, in this + order: + + X coord, Y coord, pressure, X tilt, Y tilt + Pressure and tilt should be represented natively as floats; unfortunately, + we can't do that. Again, GTK seems to record the min/max of each valuator, + and then perform scaling back to float itself using that info. Soo.... */ + + int valuators[5] = {pointer_x, pointer_y, + pressure * INT32_MAX * 1.0f, + tilt_x * INT32_MAX * 1.0f, + tilt_y * INT32_MAX * 1.0f}; + if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) { // Mimic multi-button mouse with modifier-clicks // If both sets of modifiers are pressed, // button 2 is clicked. if ((old_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) { - DarwinSimulateMouseClick(pointer_x, pointer_y, 2, darwinFakeMouse2Mask); + DarwinSimulateMouseClick(pointer_x, pointer_y, pressure, + tilt_x, tilt_y, 2, darwinFakeMouse2Mask); darwinFakeMouseButtonDown = 2; darwinFakeMouseButtonMask = darwinFakeMouse2Mask; return; } else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) { - DarwinSimulateMouseClick(pointer_x, pointer_y, 3, darwinFakeMouse3Mask); + DarwinSimulateMouseClick(pointer_x, pointer_y, pressure, + tilt_x, tilt_y, 3, darwinFakeMouse3Mask); darwinFakeMouseButtonDown = 3; darwinFakeMouseButtonMask = darwinFakeMouse3Mask; return; @@ -412,7 +434,7 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin } num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button, - POINTER_ABSOLUTE, 0, 2, valuators); + POINTER_ABSOLUTE, 0, 5, valuators); for(i=0; i 0.0f ? 4 : 5; - int valuators[2] = {pointer_x, pointer_y}; + int valuators[5] = {pointer_x, pointer_y, + pressure * INT32_MAX * 1.0f, + tilt_x * INT32_MAX * 1.0f, + tilt_y * INT32_MAX * 1.0f}; for (count = fabs(count); count > 0.0; count = count - 1.0f) { int num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonPress, ev_button, - POINTER_ABSOLUTE, 0, 2, valuators); + POINTER_ABSOLUTE, 0, 5, valuators); for(i=0; i Date: Tue, 1 Apr 2008 15:27:06 +0300 Subject: [PATCH 06/34] XKB: Fix processInputProc wrapping If input processing is frozen, only wrap realInputProc: don't smash processInputProc as well. When input processing is thawed, pIP will be rewrapped correctly. This supersedes the previous workaround in 50e80c9. Signed-off-by: Daniel Stone --- include/xkbsrv.h | 16 ++++++++++++---- xkb/xkbActions.c | 9 ++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index ef99e94e7b..040bb936ab 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -237,6 +237,14 @@ typedef struct _XkbSrvLedInfo { typedef struct { ProcessInputProc processInputProc; + /* If processInputProc is set to something different than realInputProc, + * UNWRAP and COND_WRAP will not touch processInputProc and update only + * realInputProc. This ensures that + * processInputProc == (frozen ? EnqueueEvent : realInputProc) + * + * WRAP_PROCESS_INPUT_PROC should only be called during initialization, + * since it may destroy this invariant. + */ ProcessInputProc realInputProc; DeviceUnwrapProc unwrapProc; } xkbDeviceInfoRec, *xkbDeviceInfoPtr; @@ -254,14 +262,14 @@ typedef struct device->public.processInputProc = proc; \ oldprocs->processInputProc = \ oldprocs->realInputProc = device->public.realInputProc; \ - if (proc != device->public.enqueueInputProc) \ - device->public.realInputProc = proc; \ + device->public.realInputProc = proc; \ oldprocs->unwrapProc = device->unwrapProc; \ device->unwrapProc = unwrapproc; #define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \ - backupproc = device->public.processInputProc; \ - device->public.processInputProc = oldprocs->processInputProc; \ + backupproc = device->public.realInputProc; \ + if (device->public.processInputProc == device->public.realInputProc)\ + device->public.processInputProc = oldprocs->realInputProc; \ device->public.realInputProc = oldprocs->realInputProc; \ device->unwrapProc = oldprocs->unwrapProc; diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 890cf42502..8c72874df7 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -49,15 +49,14 @@ xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, pointer data) { xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); - ProcessInputProc tmp = device->public.processInputProc; - ProcessInputProc dummy; /* unused, but neede for macro */ + ProcessInputProc backupproc; if(xkbPrivPtr->unwrapProc) xkbPrivPtr->unwrapProc = NULL; - UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, dummy); + UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); proc(device,data); - WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, - tmp,xkbUnwrapProc); + COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, + backupproc,xkbUnwrapProc); } From 9500033b9ecdfaf5a56a4355ffc94d74cb17ca17 Mon Sep 17 00:00:00 2001 From: Goneri Le Bouder Date: Tue, 1 Apr 2008 20:19:40 +0200 Subject: [PATCH 07/34] xfree86: don't crash in AutoConfig if the primary device is not pci Only call matchDriverFromFiles() if we found a pci device. Debian bug#472823 (http://bugs.debian.org/472823). --- hw/xfree86/common/xf86AutoConfig.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 268b50cb5f..3210e44601 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -436,9 +436,10 @@ chooseVideoDriver(void) if (!info) { ErrorF("Primary device is not PCI\n"); } - #ifdef __linux__ - matchDriverFromFiles(matches, info->vendor_id, info->device_id); + else { + matchDriverFromFiles(matches, info->vendor_id, info->device_id); + } #endif /* __linux__ */ /* TODO Handle multiple drivers claiming to support the same PCI ID */ From ebc56aca8bdfec1918cac3c8380895dfddea48ce Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Wed, 2 Apr 2008 10:43:19 +0800 Subject: [PATCH 08/34] Bug #15160: quirk Proview AY765C prefer first detailed timing --- hw/xfree86/modes/xf86EdidModes.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 777bb70c7f..f15c39642b 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -153,6 +153,11 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC) DDC->vendor.prod_id == 57364) return TRUE; + /* Proview AY765C 17" LCD. See bug #15160*/ + if (memcmp (DDC->vendor.name, "PTS", 4) == 0 && + DDC->vendor.prod_id == 765) + return TRUE; + return FALSE; } From b31de6a59044f91f8230aa581c9ca8540289c168 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 2 Apr 2008 16:29:30 +1000 Subject: [PATCH 09/34] dri2: fix crasher if DRI2Connect fails --- hw/xfree86/dri2/dri2ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index ca2e029707..d1d52a4277 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -114,7 +114,7 @@ ProcDRI2Connect(ClientPtr client) ScreenPtr pScreen; int fd; const char *driverName; - char *busId; + char *busId = NULL; unsigned int sareaHandle; REQUEST_SIZE_MATCH(xDRI2ConnectReq); From b13ab156894074fb38cc812738bc7aeeebd9614d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 12:38:36 -0400 Subject: [PATCH 10/34] dri2: Unbreak glcore visual setup. --- GL/glx/glxglcore.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index bbfa02b792..972ab88e6b 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -308,10 +308,9 @@ static const int glx_visual_types[] = { static __GLXconfig * createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, - VisualPtr visual, __GLXconfig *tail) + VisualPtr visual, __GLXconfig *config) { int back, depth, stencil; - __GLXconfig *config; /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ @@ -347,7 +346,7 @@ createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, config->indexBits = config->colorIndexMode ? visual->nplanes : 0; } - return tail; + return config; } static void From 7c20f65fea3dd3170cde89d7113d85f377671bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 18:00:06 -0400 Subject: [PATCH 11/34] Add @XORG_CFLAGS@ to satisfy xf86* includes. Pointed out by Hasso Tepper. --- hw/xfree86/dri/Makefile.am | 2 +- hw/xfree86/dri2/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/dri/Makefile.am b/hw/xfree86/dri/Makefile.am index 68f1eaefa3..bee315288c 100644 --- a/hw/xfree86/dri/Makefile.am +++ b/hw/xfree86/dri/Makefile.am @@ -7,7 +7,7 @@ libdri_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \ -I$(top_builddir)/GL/include \ -I@MESA_SOURCE@/include \ -DHAVE_XORG_CONFIG_H \ - @DIX_CFLAGS@ @DRIPROTO_CFLAGS@ \ + @DIX_CFLAGS@ @XORG_CFLAGS@ @DRIPROTO_CFLAGS@ \ @LIBDRM_CFLAGS@ \ @GL_CFLAGS@ libdri_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ diff --git a/hw/xfree86/dri2/Makefile.am b/hw/xfree86/dri2/Makefile.am index 844c912401..fd8962ebb2 100644 --- a/hw/xfree86/dri2/Makefile.am +++ b/hw/xfree86/dri2/Makefile.am @@ -2,7 +2,7 @@ libdri2_la_LTLIBRARIES = libdri2.la libdri2_la_CFLAGS = \ -DHAVE_XORG_CONFIG_H \ -I@MESA_SOURCE@/include \ - @DIX_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ + @DIX_CFLAGS@ @XORG_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/os-support/bus From 8cde0af3c57f0375ba8ba77af9fdf74b79d9496d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 19:06:40 -0400 Subject: [PATCH 12/34] Send the GLX_EXT_texture_from_pixmap attributes to the client. --- GL/glx/glxcmds.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 36aae61b9f..dcd83525f4 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -959,7 +959,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) return Success; } -#define __GLX_TOTAL_FBCONFIG_ATTRIBS (28) +#define __GLX_TOTAL_FBCONFIG_ATTRIBS (33) #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) /** * Send the set of GLXFBConfigs to the client. There is not currently @@ -1037,6 +1037,11 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha ); WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex ); WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod ); + WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba ); + WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets ); if (client->swapped) { __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); From b5a0a865c3045cc08c33388320d4ec3ab7065efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 19:21:41 -0400 Subject: [PATCH 13/34] Pick up dri2proto from the standard proto header include path. --- configure.ac | 2 +- hw/xfree86/dri2/dri2ext.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e72e3b99a3..985c8e2272 100644 --- a/configure.ac +++ b/configure.ac @@ -860,7 +860,7 @@ AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) if test "x$DRI2" = xyes; then # FIXME: Bump the versions once we have releases of these. AC_DEFINE(DRI2, 1, [Build DRI2 extension]) - PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.0.0]) + PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.1]) PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.3.1]) fi diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index d1d52a4277..4ae0fda3a4 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -37,12 +37,12 @@ #define NEED_REPLIES #include #include +#include #include "dixstruct.h" #include "scrnintstr.h" #include "pixmapstr.h" #include "extnsionst.h" #include "xf86drm.h" -#include "dri2proto.h" #include "dri2.h" /* The only xf86 include */ From 8746daa6732d9837f66d925f2fd74818ecbf8ba2 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 15:01:33 -0700 Subject: [PATCH 14/34] XQuartz: Fixed missing close-paren in preference pane text. (cherry picked from commit ea37e151dc6032d2a1a33cef809f2a7d507aae35) --- .../English.lproj/main.nib/designable.nib | 4 ++-- .../English.lproj/main.nib/keyedobjects.nib | Bin 38044 -> 37918 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib index 672ba904d0..c159d6ee1d 100644 --- a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib +++ b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib @@ -2,7 +2,7 @@ 1050 - 9C31 + 9C7010 639 949.26 352.00 @@ -948,7 +948,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 67239424 4194304 - When enabled, creation of a new X11 window will cause X11.app to move to the foreground (instead of Finder.app, Terminal.app, etc. + When enabled, creation of a new X11 window will cause X11.app to move to the foreground (instead of Finder.app, Terminal.app, etc.) diff --git a/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib b/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib index 91a7c5adb44e6355d01211d48fe4c5a0121a6b43..95420e4f77d13556c624c3232b9c713cb056a537 100644 GIT binary patch literal 37918 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 I=FkTJ2f!?eUH||9 literal 38044 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 Date: Mon, 31 Mar 2008 16:24:01 -0700 Subject: [PATCH 15/34] Begin to move all of our Xquartz DDX-specific event handlers to miEQ, in preparation to remove the DDX-specific code entirely. (cherry picked from commit 3f4447b95f73a82b3aa0f7b0d1640aba5fb0d1bc) --- hw/xquartz/darwinEvents.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 2a28b1a31c..b4ff9fd616 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -195,10 +195,34 @@ static void DarwinSimulateMouseClick( DarwinUpdateModifiers(KeyPress, modifierMask); } +void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { + int i; + + DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); + for (i=0; i Date: Mon, 31 Mar 2008 16:30:16 -0700 Subject: [PATCH 16/34] add logging of current thread ID to DEBUG_LOG macro (cherry picked from commit 5848510cc5a8091b30230ab920d904ca6b159480) --- hw/xquartz/darwin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index bd1b9a42a4..9384b9dbbf 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -125,7 +125,7 @@ enum { #ifdef ENABLE_DEBUG_LOG extern FILE *debug_log_fp; #define DEBUG_LOG_NAME "x11-debug.txt" -#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp); +#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%x:%s:%s:%d " msg, pthread_self(), __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp); #else #define DEBUG_LOG(msg, args...) #endif From 5b6c273eaa53d7b554d69c2b4865988068e73a26 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 17:08:45 -0700 Subject: [PATCH 17/34] add prototype for DarwinEventHandler (cherry picked from commit 9a03ae33c4f9de830f15eabf3b994882ead7c000) --- hw/xquartz/darwinEvents.c | 2 -- hw/xquartz/darwinEvents.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index b4ff9fd616..ce21ff5402 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -204,8 +204,6 @@ void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int neven Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { - void mieqSetHandler(int event, mieqHandler handler); - darwinEvents = (xEvent *)malloc(sizeof(xEvent) * GetMaximumEventsNum()); mieqInit(); mieqSetHandler(kXquartzActivate, DarwinEventHandler); diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h index 4960614201..1d8e92a7b1 100644 --- a/hw/xquartz/darwinEvents.h +++ b/hw/xquartz/darwinEvents.h @@ -41,4 +41,6 @@ void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y, float pressure, float tilt_x, float tilt_y); void DarwinUpdateModKeys(int flags); +void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, + int nevents); #endif /* _DARWIN_EVENTS_H */ From c6f0d5d1e51326e5110d27918d834eb0096df7db Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 17:48:09 -0700 Subject: [PATCH 18/34] gut darwinEQEnqueue, and make it just call mieqEnqueue (for the moment) (cherry picked from commit a9e081a60ca227c0d96d4613075d97d6b762366a) --- hw/xquartz/darwinEvents.c | 40 +++++++-------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index ce21ff5402..f7b141980d 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -199,7 +199,11 @@ void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int neven int i; DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); - for (i=0; iu.keyButtonPointer.time < darwinEventQueue.lastEventTime && - darwinEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000) - { - darwinEventQueue.events[oldtail].event.u.keyButtonPointer.time = - darwinEventQueue.lastEventTime; - } - darwinEventQueue.events[oldtail].pScreen = darwinEventQueue.pEnqueueScreen; - - // Update the tail after the event is prepared - darwinEventQueue.tail = newtail; - - // Signal there is an event ready to handle - DarwinPokeEQ(); + mieqEnqueue(NULL, e); + DarwinPokeEQ(); } - /* * DarwinEQPointerPost * Post a pointer event. Used by the mipointer.c routines. From 6c5962e44730395f81cdb333322c9ad5242c32d4 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 18:15:18 -0700 Subject: [PATCH 19/34] remove vestigal DarwinEQPointerPost etc (cherry picked from commit a25704c423598d596fd7f2ed4290d4b860bd5d5f) --- hw/xquartz/darwinEvents.c | 17 ----------------- hw/xquartz/quartzCursor.c | 4 ++-- hw/xquartz/xpr/xprCursor.c | 4 ++-- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index f7b141980d..46f5675361 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -250,23 +250,6 @@ void DarwinEQEnqueue(const xEventPtr e) { DarwinPokeEQ(); } -/* - * DarwinEQPointerPost - * Post a pointer event. Used by the mipointer.c routines. - */ -void DarwinEQPointerPost(DeviceIntPtr pdev, xEventPtr e) { - (*darwinEventQueue.pPtr->processInputProc) - (e, (DeviceIntPtr)darwinEventQueue.pPtr, 1); -} - - -void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX) { - darwinEventQueue.pEnqueueScreen = pScreen; - if (fromDIX) - darwinEventQueue.pDequeueScreen = pScreen; -} - - /* * ProcessInputEvents * Read and process events from the event queue until it is empty. diff --git a/hw/xquartz/quartzCursor.c b/hw/xquartz/quartzCursor.c index f82ccd3806..10e671a7e2 100644 --- a/hw/xquartz/quartzCursor.c +++ b/hw/xquartz/quartzCursor.c @@ -539,8 +539,8 @@ static miPointerScreenFuncRec quartzScreenFuncsRec = { QuartzCursorOffScreen, QuartzCrossScreen, QuartzWarpCursor, - DarwinEQPointerPost, - DarwinEQSwitchScreen + NULL, + NULL }; diff --git a/hw/xquartz/xpr/xprCursor.c b/hw/xquartz/xpr/xprCursor.c index e084ef90e4..2ad8d6f565 100644 --- a/hw/xquartz/xpr/xprCursor.c +++ b/hw/xquartz/xpr/xprCursor.c @@ -320,8 +320,8 @@ static miPointerScreenFuncRec quartzScreenFuncsRec = { QuartzCursorOffScreen, QuartzCrossScreen, QuartzWarpCursor, - DarwinEQPointerPost, - DarwinEQSwitchScreen + NULL, + NULL }; From aa6d12e93e8661da841192ef7c3aa7c6a7731c7f Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 17:46:59 -0700 Subject: [PATCH 20/34] turns out we weren't actually using these files. oops (cherry picked from commit bfec44d7b4baf0ad0aae55c8209bc60ac93c5b58) --- hw/xquartz/Makefile.am | 2 - hw/xquartz/quartzCursor.c | 646 -------------------------------------- hw/xquartz/quartzCursor.h | 42 --- 3 files changed, 690 deletions(-) delete mode 100644 hw/xquartz/quartzCursor.c delete mode 100644 hw/xquartz/quartzCursor.h diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am index 99d23eb1fd..0753824763 100644 --- a/hw/xquartz/Makefile.am +++ b/hw/xquartz/Makefile.am @@ -50,8 +50,6 @@ EXTRA_DIST = \ quartz.h \ quartzAudio.h \ quartzCommon.h \ - quartzCursor.c \ - quartzCursor.h \ quartzForeground.h \ quartzKeyboard.h \ quartzPasteboard.h diff --git a/hw/xquartz/quartzCursor.c b/hw/xquartz/quartzCursor.c deleted file mode 100644 index 10e671a7e2..0000000000 --- a/hw/xquartz/quartzCursor.c +++ /dev/null @@ -1,646 +0,0 @@ -/************************************************************** - * - * Support for using the Quartz Window Manager cursor - * - * Copyright (c) 2001-2003 Torrey T. Lyons and Greg Parker. - * 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, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "quartzCommon.h" -#include "quartzCursor.h" -#include "darwin.h" - -#include - -#include "mi.h" -#include "scrnintstr.h" -#include "cursorstr.h" -#include "mipointrst.h" -#include "globals.h" - -// Size of the QuickDraw cursor -#define CURSORWIDTH 16 -#define CURSORHEIGHT 16 - -typedef struct { - int qdCursorMode; - int qdCursorVisible; - int useQDCursor; - QueryBestSizeProcPtr QueryBestSize; - miPointerSpriteFuncPtr spriteFuncs; -} QuartzCursorScreenRec, *QuartzCursorScreenPtr; - -static DevPrivateKey darwinCursorScreenKey = &darwinCursorScreenKey; -static CursorPtr quartzLatentCursor = NULL; -static QD_Cursor gQDArrow; // QuickDraw arrow cursor - -// Cursor for the main thread to set (NULL = arrow cursor). -static CCrsrHandle currentCursor = NULL; -static pthread_mutex_t cursorMutex; -static pthread_cond_t cursorCondition; - -#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \ - dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey)) - -#define HIDE_QD_CURSOR(pScreen, visible) \ - if (visible) { \ - int ix; \ - for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \ - CGDisplayHideCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \ - } \ - visible = FALSE; \ - } ((void)0) - -#define SHOW_QD_CURSOR(pScreen, visible) \ - { \ - int ix; \ - for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \ - CGDisplayShowCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \ - } \ - visible = TRUE; \ - } ((void)0) - -#define CHANGE_QD_CURSOR(cursorH) \ - if (!quartzServerQuitting) { \ - /* Acquire lock and tell the main thread to change cursor */ \ - pthread_mutex_lock(&cursorMutex); \ - currentCursor = (CCrsrHandle) (cursorH); \ - QuartzMessageMainThread(kQuartzCursorUpdate, NULL, 0); \ - \ - /* Wait for the main thread to change the cursor */ \ - pthread_cond_wait(&cursorCondition, &cursorMutex); \ - pthread_mutex_unlock(&cursorMutex); \ - } ((void)0) - - -/* - * MakeQDCursor helpers: CTAB_ENTER, interleave - */ - -// Add a color entry to a ctab -#define CTAB_ENTER(ctab, index, r, g, b) \ - ctab->ctTable[index].value = index; \ - ctab->ctTable[index].rgb.red = r; \ - ctab->ctTable[index].rgb.green = g; \ - ctab->ctTable[index].rgb.blue = b - -// Make an unsigned short by interleaving the bits of bytes c1 and c2. -// High bit of c1 is first; low bit of c2 is last. -// Interleave is a built-in INTERCAL operator. -static unsigned short -interleave( - unsigned char c1, - unsigned char c2 ) -{ - return - ((c1 & 0x80) << 8) | ((c2 & 0x80) << 7) | - ((c1 & 0x40) << 7) | ((c2 & 0x40) << 6) | - ((c1 & 0x20) << 6) | ((c2 & 0x20) << 5) | - ((c1 & 0x10) << 5) | ((c2 & 0x10) << 4) | - ((c1 & 0x08) << 4) | ((c2 & 0x08) << 3) | - ((c1 & 0x04) << 3) | ((c2 & 0x04) << 2) | - ((c1 & 0x02) << 2) | ((c2 & 0x02) << 1) | - ((c1 & 0x01) << 1) | ((c2 & 0x01) << 0) ; -} - -/* - * MakeQDCursor - * Make a QuickDraw color cursor from the given X11 cursor. - * Warning: This code is nasty. Color cursors were meant to be read - * from resources; constructing the structures programmatically is messy. - */ -/* - QuickDraw cursor representation: - Our color cursor is a 2 bit per pixel pixmap. - Each pixel's bits are (source<<1 | mask) from the original X cursor pixel. - The cursor's color table maps the colors like this: - (2-bit value | X result | colortable | Mac result) - 00 | transparent | white | transparent (white outside mask) - 01 | back color | back color | back color - 10 | undefined | black | invert background (just for fun) - 11 | fore color | fore color | fore color -*/ -static CCrsrHandle -MakeQDCursor( - CursorPtr pCursor ) -{ - CCrsrHandle result; - CCrsrPtr curs; - int i, w, h; - unsigned short rowMask; - PixMap *pix; - ColorTable *ctab; - unsigned short *image; - - result = (CCrsrHandle) NewHandleClear(sizeof(CCrsr)); - if (!result) return NULL; - HLock((Handle)result); - curs = *result; - - // Initialize CCrsr - curs->crsrType = 0x8001; // 0x8000 = b&w, 0x8001 = color - curs->crsrMap = (PixMapHandle) NewHandleClear(sizeof(PixMap)); - if (!curs->crsrMap) goto pixAllocFailed; - HLock((Handle)curs->crsrMap); - pix = *curs->crsrMap; - curs->crsrData = NULL; // raw cursor image data (set below) - curs->crsrXData = NULL; // QD's processed data - curs->crsrXValid = 0; // zero means QD must re-process cursor data - curs->crsrXHandle = NULL; // reserved - memset(curs->crsr1Data, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w data - memset(curs->crsrMask, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w & color mask - curs->crsrHotSpot.h = min(CURSORWIDTH, pCursor->bits->xhot); // hot spot - curs->crsrHotSpot.v = min(CURSORHEIGHT, pCursor->bits->yhot); // hot spot - curs->crsrXTable = 0; // reserved - curs->crsrID = GetCTSeed(); // unique ID from Color Manager - - // Set the b&w data and mask - w = min(pCursor->bits->width, CURSORWIDTH); - h = min(pCursor->bits->height, CURSORHEIGHT); - rowMask = ~((1 << (CURSORWIDTH - w)) - 1); - for (i = 0; i < h; i++) { - curs->crsr1Data[i] = rowMask & - ((pCursor->bits->source[i*4]<<8) | pCursor->bits->source[i*4+1]); - curs->crsrMask[i] = rowMask & - ((pCursor->bits->mask[i*4]<<8) | pCursor->bits->mask[i*4+1]); - } - - // Set the color data and mask - // crsrMap: defines bit depth and size and colortable only - pix->rowBytes = (CURSORWIDTH * 2 / 8) | 0x8000; // last bit on means PixMap - SetRect(&pix->bounds, 0, 0, CURSORWIDTH, CURSORHEIGHT); // see TN 1020 - pix->pixelSize = 2; - pix->cmpCount = 1; - pix->cmpSize = 2; - // pix->pmTable set below - - // crsrData is the pixel data. crsrMap's baseAddr is not used. - curs->crsrData = NewHandleClear(CURSORWIDTH*CURSORHEIGHT * 2 / 8); - if (!curs->crsrData) goto imageAllocFailed; - HLock((Handle)curs->crsrData); - image = (unsigned short *) *curs->crsrData; - // Pixel data is just 1-bit data and mask interleaved (see above) - for (i = 0; i < h; i++) { - unsigned char s, m; - s = pCursor->bits->source[i*4] & (rowMask >> 8); - m = pCursor->bits->mask[i*4] & (rowMask >> 8); - image[2*i] = interleave(s, m); - s = pCursor->bits->source[i*4+1] & (rowMask & 0x00ff); - m = pCursor->bits->mask[i*4+1] & (rowMask & 0x00ff); - image[2*i+1] = interleave(s, m); - } - - // Build the color table (entries described above) - // NewPixMap allocates a color table handle. - pix->pmTable = (CTabHandle) NewHandleClear(sizeof(ColorTable) + 3 - * sizeof(ColorSpec)); - if (!pix->pmTable) goto ctabAllocFailed; - HLock((Handle)pix->pmTable); - ctab = *pix->pmTable; - ctab->ctSeed = GetCTSeed(); - ctab->ctFlags = 0; - ctab->ctSize = 3; // color count - 1 - CTAB_ENTER(ctab, 0, 0xffff, 0xffff, 0xffff); - CTAB_ENTER(ctab, 1, pCursor->backRed, pCursor->backGreen, - pCursor->backBlue); - CTAB_ENTER(ctab, 2, 0x0000, 0x0000, 0x0000); - CTAB_ENTER(ctab, 3, pCursor->foreRed, pCursor->foreGreen, - pCursor->foreBlue); - - HUnlock((Handle)pix->pmTable); // ctab - HUnlock((Handle)curs->crsrData); // image data - HUnlock((Handle)curs->crsrMap); // pix - HUnlock((Handle)result); // cursor - - return result; - - // "What we have here is a failure to allocate" -ctabAllocFailed: - HUnlock((Handle)curs->crsrData); - DisposeHandle((Handle)curs->crsrData); -imageAllocFailed: - HUnlock((Handle)curs->crsrMap); - DisposeHandle((Handle)curs->crsrMap); -pixAllocFailed: - HUnlock((Handle)result); - DisposeHandle((Handle)result); - return NULL; -} - - -/* - * FreeQDCursor - * Destroy a QuickDraw color cursor created with MakeQDCursor(). - * The cursor must not currently be on screen. - */ -static void FreeQDCursor(CCrsrHandle cursHandle) -{ - CCrsrPtr curs; - PixMap *pix; - - HLock((Handle)cursHandle); - curs = *cursHandle; - HLock((Handle)curs->crsrMap); - pix = *curs->crsrMap; - DisposeHandle((Handle)pix->pmTable); - HUnlock((Handle)curs->crsrMap); - DisposeHandle((Handle)curs->crsrMap); - DisposeHandle((Handle)curs->crsrData); - HUnlock((Handle)cursHandle); - DisposeHandle((Handle)cursHandle); -} - - -/* -=========================================================================== - - Pointer sprite functions - -=========================================================================== -*/ - -/* - * QuartzRealizeCursor - * Convert the X cursor representation to QuickDraw format if possible. - */ -Bool -QuartzRealizeCursor( - ScreenPtr pScreen, - CursorPtr pCursor ) -{ - CCrsrHandle qdCursor; - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if(!pCursor || !pCursor->bits) - return FALSE; - - // if the cursor is too big we use a software cursor - if ((pCursor->bits->height > CURSORHEIGHT) || - (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor) - { - if (quartzRootless) { - // rootless can't use a software cursor - return TRUE; - } else { - return (*ScreenPriv->spriteFuncs->RealizeCursor) - (pScreen, pCursor); - } - } - - // make new cursor image - qdCursor = MakeQDCursor(pCursor); - if (!qdCursor) return FALSE; - - // save the result - dixSetPrivate(&pCursor->devPrivates, pScreen, qdCursor); - - return TRUE; -} - - -/* - * QuartzUnrealizeCursor - * Free the storage space associated with a realized cursor. - */ -Bool -QuartzUnrealizeCursor( - ScreenPtr pScreen, - CursorPtr pCursor ) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if ((pCursor->bits->height > CURSORHEIGHT) || - (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor) - { - if (quartzRootless) { - return TRUE; - } else { - return (*ScreenPriv->spriteFuncs->UnrealizeCursor) - (pScreen, pCursor); - } - } else { - CCrsrHandle oldCursor = dixLookupPrivate(&pCursor->devPrivates, - pScreen); - if (currentCursor != oldCursor) { - // This should only fail when quitting, in which case we just leak. - FreeQDCursor(oldCursor); - } - dixSetPrivate(&pCursor->devPrivates, pScreen, NULL); - return TRUE; - } -} - - -/* - * QuartzSetCursor - * Set the cursor sprite and position. - * Use QuickDraw cursor if possible. - */ -static void -QuartzSetCursor( - ScreenPtr pScreen, - CursorPtr pCursor, - int x, - int y) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - quartzLatentCursor = pCursor; - - // Don't touch Mac OS cursor if X is hidden! - if (!quartzServerVisible) - return; - - if (!pCursor) { - // Remove the cursor completely. - HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - if (! ScreenPriv->qdCursorMode) - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y); - } - else if ((pCursor->bits->height <= CURSORHEIGHT) && - (pCursor->bits->width <= CURSORWIDTH) && ScreenPriv->useQDCursor) - { - // Cursor is small enough to use QuickDraw directly. - if (! ScreenPriv->qdCursorMode) // remove the X cursor - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y); - ScreenPriv->qdCursorMode = TRUE; - - CHANGE_QD_CURSOR(dixLookupPrivate(&pCursor->devPrivates, pScreen)); - SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - } - else if (quartzRootless) { - // Rootless can't use a software cursor, so we just use Mac OS arrow. - CHANGE_QD_CURSOR(NULL); - SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - } - else { - // Cursor is too big for QuickDraw. Use X software cursor. - HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - ScreenPriv->qdCursorMode = FALSE; - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y); - } -} - - -/* - * QuartzReallySetCursor - * Set the QuickDraw cursor. Called from the main thread since changing the - * cursor with QuickDraw is not thread safe on dual processor machines. - */ -void -QuartzReallySetCursor() -{ - pthread_mutex_lock(&cursorMutex); - - if (currentCursor) { - SetCCursor(currentCursor); - } else { - SetCursor(&gQDArrow); - } - - pthread_cond_signal(&cursorCondition); - pthread_mutex_unlock(&cursorMutex); -} - - -/* - * QuartzMoveCursor - * Move the cursor. This is a noop for QuickDraw. - */ -static void -QuartzMoveCursor( - ScreenPtr pScreen, - int x, - int y) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - // only the X cursor needs to be explicitly moved - if (!ScreenPriv->qdCursorMode) - (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y); -} - - -static miPointerSpriteFuncRec quartzSpriteFuncsRec = { - QuartzRealizeCursor, - QuartzUnrealizeCursor, - QuartzSetCursor, - QuartzMoveCursor -}; - - -/* -=========================================================================== - - Pointer screen functions - -=========================================================================== -*/ - -/* - * QuartzCursorOffScreen - */ -static Bool QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) -{ - return FALSE; -} - - -/* - * QuartzCrossScreen - */ -static void QuartzCrossScreen(ScreenPtr pScreen, Bool entering) -{ - return; -} - - -/* - * QuartzWarpCursor - * Change the cursor position without generating an event or motion history. - * The input coordinates (x,y) are in pScreen-local X11 coordinates. - * - */ -static void -QuartzWarpCursor( - ScreenPtr pScreen, - int x, - int y) -{ - static int neverMoved = TRUE; - - if (neverMoved) { - // Don't move the cursor the first time. This is the jump-to-center - // initialization, and it's annoying because we may still be in MacOS. - neverMoved = FALSE; - return; - } - - if (quartzServerVisible) { - CGDisplayErr cgErr; - CGPoint cgPoint; - // Only need to do this for one display. Any display will do. - CGDirectDisplayID cgID = QUARTZ_PRIV(pScreen)->displayIDs[0]; - CGRect cgRect = CGDisplayBounds(cgID); - - // Convert (x,y) to CoreGraphics screen-local CG coordinates. - // This is necessary because the X11 screen and CG screen may not - // coincide. (e.g. X11 screen may be moved to dodge the menu bar) - - // Make point in X11 global coordinates - cgPoint = CGPointMake(x + dixScreenOrigins[pScreen->myNum].x, - y + dixScreenOrigins[pScreen->myNum].y); - // Shift to CoreGraphics global screen coordinates - cgPoint.x += darwinMainScreenX; - cgPoint.y += darwinMainScreenY; - // Shift to CoreGraphics screen-local coordinates - cgPoint.x -= cgRect.origin.x; - cgPoint.y -= cgRect.origin.y; - - cgErr = CGDisplayMoveCursorToPoint(cgID, cgPoint); - if (cgErr != CGDisplayNoErr) { - ErrorF("Could not set cursor position with error code 0x%x.\n", - cgErr); - } - } - - miPointerWarpCursor(pScreen, x, y); - miPointerUpdate(); -} - - -static miPointerScreenFuncRec quartzScreenFuncsRec = { - QuartzCursorOffScreen, - QuartzCrossScreen, - QuartzWarpCursor, - NULL, - NULL -}; - - -/* -=========================================================================== - - Other screen functions - -=========================================================================== -*/ - -/* - * QuartzCursorQueryBestSize - * Handle queries for best cursor size - */ -static void -QuartzCursorQueryBestSize( - int class, - unsigned short *width, - unsigned short *height, - ScreenPtr pScreen) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if (class == CursorShape) { - *width = CURSORWIDTH; - *height = CURSORHEIGHT; - } else { - (*ScreenPriv->QueryBestSize)(class, width, height, pScreen); - } -} - - -/* - * QuartzInitCursor - * Initialize cursor support - */ -Bool -QuartzInitCursor( - ScreenPtr pScreen ) -{ - QuartzCursorScreenPtr ScreenPriv; - miPointerScreenPtr PointPriv; - DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); - - // initialize software cursor handling (always needed as backup) - if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) { - return FALSE; - } - - ScreenPriv = xcalloc( 1, sizeof(QuartzCursorScreenRec) ); - if (!ScreenPriv) return FALSE; - - CURSOR_PRIV(pScreen) = ScreenPriv; - - // override some screen procedures - ScreenPriv->QueryBestSize = pScreen->QueryBestSize; - pScreen->QueryBestSize = QuartzCursorQueryBestSize; - - // initialize QuickDraw cursor handling - GetQDGlobalsArrow(&gQDArrow); - PointPriv = (miPointerScreenPtr) - dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - - ScreenPriv->spriteFuncs = PointPriv->spriteFuncs; - PointPriv->spriteFuncs = &quartzSpriteFuncsRec; - - if (!quartzRootless) - ScreenPriv->useQDCursor = QuartzFSUseQDCursor(dfb->colorBitsPerPixel); - else - ScreenPriv->useQDCursor = TRUE; - ScreenPriv->qdCursorMode = TRUE; - ScreenPriv->qdCursorVisible = TRUE; - - // initialize cursor mutex lock - pthread_mutex_init(&cursorMutex, NULL); - - // initialize condition for waiting - pthread_cond_init(&cursorCondition, NULL); - - return TRUE; -} - - -// X server is hiding. Restore the Aqua cursor. -void QuartzSuspendXCursor( - ScreenPtr pScreen ) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - CHANGE_QD_CURSOR(NULL); - SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); -} - - -// X server is showing. Restore the X cursor. -void QuartzResumeXCursor( - ScreenPtr pScreen, - int x, - int y ) -{ - QuartzSetCursor(pScreen, quartzLatentCursor, x, y); -} diff --git a/hw/xquartz/quartzCursor.h b/hw/xquartz/quartzCursor.h deleted file mode 100644 index 56a02098da..0000000000 --- a/hw/xquartz/quartzCursor.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * quartzCursor.h - * - * External interface for Quartz hardware cursor - * - * Copyright (c) 2001 Torrey T. Lyons and Greg Parker. - * 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, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifndef QUARTZCURSOR_H -#define QUARTZCURSOR_H - -#include "screenint.h" - -Bool QuartzInitCursor(ScreenPtr pScreen); -void QuartzReallySetCursor(void); -void QuartzSuspendXCursor(ScreenPtr pScreen); -void QuartzResumeXCursor(ScreenPtr pScreen, int x, int y); - -#endif From 8944b77ec0c18476a25ba3179bcc45b338be22b8 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 17:47:42 -0700 Subject: [PATCH 21/34] continue with gutting darwinEvents.c (cherry picked from commit c34fce7051b996633291dddc061b696ff737f3fb) --- hw/xquartz/darwinEvents.c | 124 +++++++++----------------------------- 1 file changed, 28 insertions(+), 96 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 46f5675361..5b037d2fad 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -78,7 +78,7 @@ typedef struct _EventQueue { } EventQueueRec, *EventQueuePtr; static EventQueueRec darwinEventQueue; -xEvent *darwinEvents; +xEvent *darwinEvents = NULL; /* * DarwinPressModifierMask @@ -207,8 +207,11 @@ void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int neven } Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { + if (!darwinEvents) + darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!darwinEvents) + FatalError("Couldn't allocate event buffer\n"); - darwinEvents = (xEvent *)malloc(sizeof(xEvent) * GetMaximumEventsNum()); mieqInit(); mieqSetHandler(kXquartzActivate, DarwinEventHandler); mieqSetHandler(kXquartzDeactivate, DarwinEventHandler); @@ -225,13 +228,6 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { mieqSetHandler(kXquartzWindowState, DarwinEventHandler); mieqSetHandler(kXquartzWindowMoved, DarwinEventHandler); - darwinEventQueue.head = darwinEventQueue.tail = 0; - darwinEventQueue.lastEventTime = GetTimeInMillis (); - darwinEventQueue.pKbd = pKbd; - darwinEventQueue.pPtr = pPtr; - darwinEventQueue.pEnqueueScreen = screenInfo.screens[0]; - darwinEventQueue.pDequeueScreen = darwinEventQueue.pEnqueueScreen; - SetInputCheck(&input_check_zero, &input_check_flag); return TRUE; } @@ -255,8 +251,6 @@ void DarwinEQEnqueue(const xEventPtr e) { * Read and process events from the event queue until it is empty. */ void ProcessInputEvents(void) { - EventRec *e; - int x, y; xEvent xe; // button number and modifier mask of currently pressed fake button input_check_flag=0; @@ -265,92 +259,11 @@ void ProcessInputEvents(void) { mieqProcessInputEvents(); // Empty the signaling pipe - x = sizeof(xe); - while (x == sizeof(xe)) - x = read(darwinEventReadFD, &xe, sizeof(xe)); - - while (darwinEventQueue.head != darwinEventQueue.tail) - { - if (screenIsSaved == SCREEN_SAVER_ON) - dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); - - e = &darwinEventQueue.events[darwinEventQueue.head]; - xe = e->event; - - // Shift from global screen coordinates to coordinates relative to - // the origin of the current screen. - xe.u.keyButtonPointer.rootX -= darwinMainScreenX + - dixScreenOrigins[miPointerCurrentScreen()->myNum].x; - xe.u.keyButtonPointer.rootY -= darwinMainScreenY + - dixScreenOrigins[miPointerCurrentScreen()->myNum].y; - - /* ErrorF("old rootX = (%d,%d) darwinMainScreen = (%d,%d) dixScreenOrigins[%d]=(%d,%d)\n", - xe.u.keyButtonPointer.rootX, xe.u.keyButtonPointer.rootY, - darwinMainScreenX, darwinMainScreenY, - miPointerCurrentScreen()->myNum, - dixScreenOrigins[miPointerCurrentScreen()->myNum].x, - dixScreenOrigins[miPointerCurrentScreen()->myNum].y); */ - - //Assumption - screen switching can only occur on motion events - - if (e->pScreen != darwinEventQueue.pDequeueScreen) - { - darwinEventQueue.pDequeueScreen = e->pScreen; - x = xe.u.keyButtonPointer.rootX; - y = xe.u.keyButtonPointer.rootY; - if (darwinEventQueue.head == QUEUE_SIZE - 1) - darwinEventQueue.head = 0; - else - ++darwinEventQueue.head; - NewCurrentScreen (darwinEventQueue.pDequeueScreen, x, y); - } - else - { - if (darwinEventQueue.head == QUEUE_SIZE - 1) - darwinEventQueue.head = 0; - else - ++darwinEventQueue.head; - switch (xe.u.u.type) { - case KeyPress: - case KeyRelease: - ErrorF("Unexpected Keyboard event in DarwinProcessInputEvents\n"); - break; - - case ButtonPress: - ErrorF("Unexpected ButtonPress event in DarwinProcessInputEvents\n"); - break; - - case ButtonRelease: - ErrorF("Unexpected ButtonRelease event in DarwinProcessInputEvents\n"); - break; - - case MotionNotify: - ErrorF("Unexpected MotionNotify event in DarwinProcessInputEvents\n"); - break; - - case kXquartzUpdateModifiers: - ErrorF("Unexpected kXquartzUpdateModifiers event in DarwinProcessInputEvents\n"); - break; - - case kXquartzUpdateButtons: - ErrorF("Unexpected kXquartzUpdateButtons event in DarwinProcessInputEvents\n"); - break; - - case kXquartzScrollWheel: - ErrorF("Unexpected kXquartzScrollWheel event in DarwinProcessInputEvents\n"); - break; - - case kXquartzDeactivate: - DarwinReleaseModifiers(); - // fall through - default: - // Check for mode specific event - QuartzProcessEvent(&xe); - } - } + int x = sizeof(xe); + while (x == sizeof(xe)) { + DEBUG_LOG("draining pipe\n"); + x = read(darwinEventReadFD, &xe, sizeof(xe)); } - - // miPointerUpdate(); } /* Sends a null byte down darwinEventWriteFD, which will cause the @@ -368,6 +281,10 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin static int darwinFakeMouseButtonMask = 0; int i, num_events; + if(!darwinEvents) { + ErrorF("DarwinSendPointerEvents called before darwinEvents was initialized\n"); + return; + } /* I can't find a spec for this, but at least GTK expects that tablets are just like mice, except they have either one or three extra valuators, in this order: @@ -421,6 +338,11 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin void DarwinSendKeyboardEvents(int ev_type, int keycode) { int i, num_events; + if(!darwinEvents) { + ErrorF("DarwinSendKeyboardEvents called before darwinEvents was initialized\n"); + return; + } + if (old_flags == 0 && darwinSyncKeymap && darwinKeymapFile == NULL) { /* See if keymap has changed. */ @@ -447,6 +369,11 @@ void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y, tilt_x * INT32_MAX * 1.0f, tilt_y * INT32_MAX * 1.0f}; + if(!darwinEvents) { + ErrorF("DarwinSendProximityvents called before darwinEvents was initialized\n"); + return; +} + num_events = GetProximityEvents(darwinEvents, darwinPointer, ev_type, 0, 5, valuators); @@ -465,6 +392,11 @@ void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y, tilt_x * INT32_MAX * 1.0f, tilt_y * INT32_MAX * 1.0f}; + if(!darwinEvents) { + ErrorF("DarwinSendScrollEvents called before darwinEvents was initialized\n"); + return; + } + for (count = fabs(count); count > 0.0; count = count - 1.0f) { int num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonPress, ev_button, POINTER_ABSOLUTE, 0, 5, valuators); From 89f1d880e83e32b72d35c4dbd6795defa6efa847 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 19:47:28 -0700 Subject: [PATCH 22/34] nuke DarwinEventQueue (cherry picked from commit 1e0ec02202eeaffae480048b91bf02140ee29f8a) --- hw/xquartz/darwinEvents.c | 33 --------------------------------- hw/xquartz/quartz.c | 2 +- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 5b037d2fad..230050f606 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -56,28 +56,10 @@ in this Software without prior written authorization from The Open Group. #define SCROLLWHEELUPFAKE 4 #define SCROLLWHEELDOWNFAKE 5 -#define QUEUE_SIZE 256 - -typedef struct _Event { - xEvent event; - ScreenPtr pScreen; -} EventRec, *EventPtr; - int input_check_zero, input_check_flag; static int old_flags = 0; // last known modifier state -typedef struct _EventQueue { - HWEventQueueType head, tail; /* long for SetInputCheck */ - CARD32 lastEventTime; /* to avoid time running backwards */ - Bool lastMotion; - EventRec events[QUEUE_SIZE]; /* static allocation for signals */ - DevicePtr pKbd, pPtr; /* device pointer, to get funcs */ - ScreenPtr pEnqueueScreen; /* screen events are being delivered to */ - ScreenPtr pDequeueScreen; /* screen events are being dispatched to */ -} EventQueueRec, *EventQueuePtr; - -static EventQueueRec darwinEventQueue; xEvent *darwinEvents = NULL; /* @@ -231,21 +213,6 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { return TRUE; } - -/* - * DarwinEQEnqueue - * Must be thread safe with ProcessInputEvents. - * DarwinEQEnqueue - called from event gathering thread - * ProcessInputEvents - called from X server thread - * DarwinEQEnqueue should never be called from more than one thread. - * - * This should be deprecated in favor of miEQEnqueue -- BB - */ -void DarwinEQEnqueue(const xEventPtr e) { - mieqEnqueue(NULL, e); - DarwinPokeEQ(); -} - /* * ProcessInputEvents * Read and process events from the event queue until it is empty. diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index 971c9b278d..5dfdeeb30c 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -401,7 +401,7 @@ QuartzMessageServerThread( va_end (args); } - DarwinEQEnqueue(&xe); + mieqEnqueue(NULL, &xe); } From 985c631b2e1f113039e6e620f030505435fd9815 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 20:18:58 -0700 Subject: [PATCH 23/34] just a bit of juggling headers around -- we're preparing to call our Xquartz-specific event handlers directly as mieqHandlers (cherry picked from commit 4aedba5aa727e22316e8ca456f7218bea9ee0313) --- hw/xquartz/darwin.c | 2 +- hw/xquartz/darwin.h | 2 +- hw/xquartz/quartz.c | 3 +++ hw/xquartz/quartzCocoa.m | 3 ++- hw/xquartz/quartzPasteboard.c | 10 ++++++---- hw/xquartz/quartzPasteboard.h | 4 ++-- hw/xquartz/xpr/xprScreen.c | 1 + 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 8f2511dbb8..002ea413d3 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -880,7 +880,7 @@ void AbortDDX( void ) */ void -xf86SetRootClip (ScreenPtr pScreen, BOOL enable) +xf86SetRootClip (ScreenPtr pScreen, int enable) { WindowPtr pWin = WindowTable[pScreen->myNum]; WindowPtr pChild; diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index 9384b9dbbf..8c3cabbd11 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -54,7 +54,7 @@ typedef struct { void DarwinPrintBanner(void); int DarwinParseModifierList(const char *constmodifiers); void DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo); -void xf86SetRootClip (ScreenPtr pScreen, BOOL enable); +void xf86SetRootClip (ScreenPtr pScreen, int enable); #define SCREEN_PRIV(pScreen) ((DarwinFramebufferPtr) \ dixLookupPrivate(&pScreen->devPrivates, darwinScreenKey)) diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index 5dfdeeb30c..ec211cf0ac 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -33,6 +33,7 @@ #endif #include "quartzCommon.h" +#include "inputstr.h" #include "quartz.h" #include "darwin.h" #include "darwinEvents.h" @@ -489,6 +490,7 @@ void QuartzProcessEvent(xEvent *xe) { GiveUp(0); break; +#if 0 case kXquartzReadPasteboard: QuartzReadPasteboard(); break; @@ -496,6 +498,7 @@ void QuartzProcessEvent(xEvent *xe) { case kXquartzWritePasteboard: QuartzWritePasteboard(); break; +#endif case kXquartzBringAllToFront: DEBUG_LOG("kXquartzBringAllToFront\n"); diff --git a/hw/xquartz/quartzCocoa.m b/hw/xquartz/quartzCocoa.m index 53e3f08979..d8f9c69e4b 100644 --- a/hw/xquartz/quartzCocoa.m +++ b/hw/xquartz/quartzCocoa.m @@ -37,13 +37,14 @@ #endif #include "quartzCommon.h" +#include "inputstr.h" #include "quartzPasteboard.h" #define BOOL xBOOL #include "darwin.h" -#undef BOOL #include +#undef BOOL #include "pseudoramiX.h" diff --git a/hw/xquartz/quartzPasteboard.c b/hw/xquartz/quartzPasteboard.c index 0bf84f5d5f..d47047ce02 100644 --- a/hw/xquartz/quartzPasteboard.c +++ b/hw/xquartz/quartzPasteboard.c @@ -34,6 +34,8 @@ #include #endif +#include "misc.h" +#include "inputstr.h" #include "quartzPasteboard.h" #include @@ -76,8 +78,8 @@ static char * QuartzReadCutBuffer(void) } // Write X cut buffer to Mac OS X pasteboard -// Called by ProcessInputEvents() in response to request from X server thread. -void QuartzWritePasteboard(void) +// Called by mieqProcessInputEvents() in response to request from X server thread. +void QuartzWritePasteboard(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { char *text; text = QuartzReadCutBuffer(); @@ -90,8 +92,8 @@ void QuartzWritePasteboard(void) #define strequal(a, b) (0 == strcmp((a), (b))) // Read Mac OS X pasteboard into X cut buffer -// Called by ProcessInputEvents() in response to request from X server thread. -void QuartzReadPasteboard(void) +// Called by mieqProcessInputEvents() in response to request from X server thread. +void QuartzReadPasteboard(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { char *oldText = QuartzReadCutBuffer(); char *text = QuartzReadCocoaPasteboard(); diff --git a/hw/xquartz/quartzPasteboard.h b/hw/xquartz/quartzPasteboard.h index d6a8ee8156..b51cd88e02 100644 --- a/hw/xquartz/quartzPasteboard.h +++ b/hw/xquartz/quartzPasteboard.h @@ -34,11 +34,11 @@ #define _QUARTZPASTEBOARD_H // Aqua->X -void QuartzReadPasteboard(void); +void QuartzReadPasteboard(int, xEventPtr, DeviceIntPtr, int); char * QuartzReadCocoaPasteboard(void); // caller must free string // X->Aqua -void QuartzWritePasteboard(void); +void QuartzWritePasteboard(int, xEventPtr, DeviceIntPtr, int); void QuartzWriteCocoaPasteboard(char *text); #endif /* _QUARTZPASTEBOARD_H */ diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index b653a6e3b3..5e144731d9 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -32,6 +32,7 @@ #endif #include "quartzCommon.h" +#include "inputstr.h" #include "quartz.h" #include "xpr.h" #include "pseudoramiX.h" From c1be4e3379d8780dff20390939b657ca0973995a Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 21:04:37 -0700 Subject: [PATCH 24/34] shovelling code around ... (cherry picked from commit 2143182ba49195bbb2e9163ea6872fd68e7a4a85) --- dix/main.c | 14 ++++ hw/xquartz/darwinEvents.c | 106 +++++++++++++++++++++++++++++-- hw/xquartz/darwinKeyboard.c | 8 +++ hw/xquartz/quartz.c | 123 ++---------------------------------- hw/xquartz/quartz.h | 2 +- 5 files changed, 130 insertions(+), 123 deletions(-) diff --git a/dix/main.c b/dix/main.c index db4347341e..8f6507f5c6 100644 --- a/dix/main.c +++ b/dix/main.c @@ -113,6 +113,9 @@ Equipment Corporation. #include "dispatch.h" /* InitProcVectors() */ #endif +#include +pthread_key_t threadname_key=0; + #ifdef DPMSExtension #define DPMS_SERVER #include @@ -248,6 +251,17 @@ main(int argc, char *argv[], char *envp[]) char *xauthfile; HWEventQueueType alwaysCheckForInput[2]; + if(threadname_key == 0) ErrorF("pthread_key_create returned %d\n", pthread_key_create(&threadname_key, NULL)); + ErrorF("threadname_key = %d\n", threadname_key); + if(pthread_getspecific(threadname_key) == NULL) { + char *nameptr = malloc(32); + sprintf(nameptr, "main thread %d", random()); + // strcpy(nameptr, "main thread"); + ErrorF("calling: pthread_setspecific(%d, %s)=%d\n", threadname_key, nameptr, pthread_setspecific(threadname_key, nameptr)); + if (pthread_getspecific(threadname_key) != NULL) ErrorF("current thread: %s\n", (char *)pthread_getspecific(threadname_key)); + } else { + if (pthread_getspecific(threadname_key) != NULL) ErrorF("thread was already: %s\n", (char *)pthread_getspecific(threadname_key)); + } display = "0"; InitGlobals(); diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 230050f606..28a712dabb 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -52,6 +52,11 @@ in this Software without prior written authorization from The Open Group. #include #include +#define _APPLEWM_SERVER_ +#include "applewmExt.h" +#include + + /* Fake button press/release for scroll wheel move. */ #define SCROLLWHEELUPFAKE 4 #define SCROLLWHEELDOWNFAKE 5 @@ -177,14 +182,103 @@ static void DarwinSimulateMouseClick( DarwinUpdateModifiers(KeyPress, modifierMask); } +/* Generic handler for Xquartz-specifc events. When possible, these should + be moved into their own individual functions and set as handlers using + mieqSetHandler. */ + void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { int i; DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); for (i=0; iu.u.type) { - case kXquartzControllerNotify: - DEBUG_LOG("kXquartzControllerNotify\n"); - AppleWMSendEvent(AppleWMControllerNotify, - AppleWMControllerNotifyMask, - xe->u.clientMessage.u.l.longs0, - xe->u.clientMessage.u.l.longs1); - break; - - case kXquartzPasteboardNotify: - DEBUG_LOG("kXquartzPasteboardNotify\n"); - AppleWMSendEvent(AppleWMPasteboardNotify, - AppleWMPasteboardNotifyMask, - xe->u.clientMessage.u.l.longs0, - xe->u.clientMessage.u.l.longs1); - break; - - case kXquartzActivate: - DEBUG_LOG("kXquartzActivate\n"); - QuartzShow(xe->u.keyButtonPointer.rootX, - xe->u.keyButtonPointer.rootY); - AppleWMSendEvent(AppleWMActivationNotify, - AppleWMActivationNotifyMask, - AppleWMIsActive, 0); - break; - - case kXquartzDeactivate: - DEBUG_LOG("kXquartzDeactivate\n"); - AppleWMSendEvent(AppleWMActivationNotify, - AppleWMActivationNotifyMask, - AppleWMIsInactive, 0); - QuartzHide(); - break; - - case kXquartzDisplayChanged: - DEBUG_LOG("kXquartzDisplayChanged\n"); - QuartzUpdateScreens(); - break; - - case kXquartzWindowState: - DEBUG_LOG("kXquartzWindowState\n"); - RootlessNativeWindowStateChanged(xe->u.clientMessage.u.l.longs0, - xe->u.clientMessage.u.l.longs1); - break; - - case kXquartzWindowMoved: - DEBUG_LOG("kXquartzWindowMoved\n"); - RootlessNativeWindowMoved ((WindowPtr)xe->u.clientMessage.u.l.longs0); - break; - - case kXquartzToggleFullscreen: - DEBUG_LOG("kXquartzToggleFullscreen\n"); -#ifdef DARWIN_DDX_MISSING - if (quartzEnableRootless) QuartzSetFullscreen(!quartzHasRoot); - else if (quartzHasRoot) QuartzHide(); - else QuartzShow(); -#else - // ErrorF("kXquartzToggleFullscreen not implemented\n"); -#endif - break; - - case kXquartzSetRootless: - DEBUG_LOG("kXquartzSetRootless\n"); -#ifdef DARWIN_DDX_MISSING - QuartzSetRootless(xe->u.clientMessage.u.l.longs0); - if (!quartzEnableRootless && !quartzHasRoot) QuartzHide(); -#else - // ErrorF("kXquartzSetRootless not implemented\n"); -#endif - break; - - case kXquartzSetRootClip: - QuartzSetRootClip((BOOL)xe->u.clientMessage.u.l.longs0); - break; - - case kXquartzQuit: - GiveUp(0); - break; - -#if 0 - case kXquartzReadPasteboard: - QuartzReadPasteboard(); - break; - - case kXquartzWritePasteboard: - QuartzWritePasteboard(); - break; -#endif - - case kXquartzBringAllToFront: - DEBUG_LOG("kXquartzBringAllToFront\n"); - RootlessOrderAllWindows(); - break; - - case kXquartzSpaceChanged: - DEBUG_LOG("kXquartzSpaceChanged\n"); - QuartzSpaceChanged(xe->u.clientMessage.u.l.longs0); - break; - default: - ErrorF("Unknown application defined event type %d.\n", xe->u.u.type); - } -} diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h index fbe308a92a..ffe06f9c6b 100644 --- a/hw/xquartz/quartz.h +++ b/hw/xquartz/quartz.h @@ -130,5 +130,5 @@ void QuartzInitOutput(int argc,char **argv); void QuartzInitInput(int argc, char **argv); void QuartzGiveUp(void); void QuartzProcessEvent(xEvent *xe); - +void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents); #endif From e9e2d88436597875f102085d216dc0a8fce1450a Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 22:55:24 -0700 Subject: [PATCH 25/34] moved and renamed QuartzMessageServerThread to DarwinSendDDXEvent to make more clear what it actually does. (cherry picked from commit bee2b377efc930e25017636e5112093a3a6549c7) --- hw/xquartz/X11Application.m | 14 +++++++------- hw/xquartz/X11Controller.m | 32 ++++++++++++++++---------------- hw/xquartz/darwin.h | 3 +++ hw/xquartz/darwinEvents.c | 28 ++++++++++++++++++++++++++++ hw/xquartz/darwinEvents.h | 2 ++ hw/xquartz/quartz.c | 31 ------------------------------- hw/xquartz/xpr/xprScreen.c | 8 ++++---- 7 files changed, 60 insertions(+), 58 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 147b4b4c0e..28bb529951 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -1,6 +1,6 @@ /* X11Application.m -- subclass of NSApplication to multiplex events - Copyright (c) 2002-2007 Apple Inc. + Copyright (c) 2002-2008 Apple Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -166,7 +166,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { static TSMDocumentID x11_document; DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active) if (state) { - QuartzMessageServerThread (kXquartzActivate, 0); + DarwinSendDDXEvent(kXquartzActivate, 0); if (!_x_active) { if (x11_document == 0 && darwinKeymapFile == NULL) { @@ -178,10 +178,10 @@ static void message_kit_thread (SEL selector, NSObject *arg) { if (x11_document != 0) ActivateTSMDocument (x11_document); } } else { - QuartzMessageServerThread (kXquartzDeactivate, 0); + DarwinSendDDXEvent(kXquartzDeactivate, 0); if (_x_active && x11_document != 0) - DeactivateTSMDocument (x11_document); + DeactivateTSMDocument (x11_document); } _x_active = state; @@ -246,7 +246,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { swallow_up = 0; for_x = NO; #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXquartzToggleFullscreen, 0); + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); #endif } } else { @@ -271,7 +271,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { case NSApplicationActivatedEventType: for_x = NO; if ([self modalWindow] == nil) { - for_appkit = NO; + for_appkit = NO; /* FIXME: hack to avoid having to pass the event to appkit, which would cause it to raise one of its windows. */ @@ -654,7 +654,7 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { /* This will end up at the end of the responder chain. */ - (void) copy:sender { - QuartzMessageServerThread (kXquartzPasteboardNotify, 1, + DarwinSendDDXEvent(kXquartzPasteboardNotify, 1, AppleWMCopyToPasteboard); } diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m index aa9fa94beb..5bf4f4d52c 100644 --- a/hw/xquartz/X11Controller.m +++ b/hw/xquartz/X11Controller.m @@ -1,6 +1,6 @@ /* X11Controller.m -- connect the IB ui, also the NSApp delegate - Copyright (c) 2002-2007 Apple Inc. All rights reserved. + Copyright (c) 2002-2008 Apple Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -103,7 +103,7 @@ { [NSApp activateIgnoringOtherApps:YES]; - QuartzMessageServerThread (kXquartzControllerNotify, 2, + DarwinSendDDXEvent(kXquartzControllerNotify, 2, AppleWMWindowMenuItem, [sender tag]); } @@ -254,7 +254,7 @@ [self remove_window_menu]; [self install_window_menu:list]; - QuartzMessageServerThread (kXquartzControllerNotify, 1, + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMWindowMenuNotify); } @@ -539,20 +539,20 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (void) hide_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMHideWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideWindow); else NSBeep (); /* FIXME: something here */ } - (IBAction)bring_to_front:sender { - QuartzMessageServerThread(kXquartzControllerNotify, 1, AppleWMBringAllToFront); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMBringAllToFront); } - (IBAction)close_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMCloseWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMCloseWindow); else [[NSApp keyWindow] performClose:sender]; } @@ -560,7 +560,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction)minimize_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMMinimizeWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMMinimizeWindow); else [[NSApp keyWindow] performMiniaturize:sender]; } @@ -568,19 +568,19 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction)zoom_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMZoomWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMZoomWindow); else [[NSApp keyWindow] performZoom:sender]; } - (IBAction) next_window:sender { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMNextWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMNextWindow); } - (IBAction) previous_window:sender { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMPreviousWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMPreviousWindow); } - (IBAction) enable_fullscreen_changed:sender @@ -588,7 +588,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row int value = ![enable_fullscreen intValue]; #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXquartzSetRootless, 1, value); + DarwinSendDDXEvent(kXquartzSetRootless, 1, value); #endif [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value]; @@ -598,7 +598,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction) toggle_fullscreen:sender { #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXquartzToggleFullscreen, 0); + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); #endif } @@ -661,7 +661,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction) quit:sender { - QuartzMessageServerThread (kXquartzQuit, 0); + DarwinSendDDXEvent(kXquartzQuit, 0); } - (IBAction) x11_help:sender @@ -684,12 +684,12 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (void) applicationDidHide:(NSNotification *)notify { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMHideAll); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideAll); } - (void) applicationDidUnhide:(NSNotification *)notify { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMShowAll); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMShowAll); } - (NSApplicationTerminateReply) applicationShouldTerminate:sender @@ -717,7 +717,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row [X11App prefs_synchronize]; /* shutdown the X server, it will exit () for us. */ - QuartzMessageServerThread (kXquartzQuit, 0); + DarwinSendDDXEvent(kXquartzQuit, 0); /* In case it doesn't, exit anyway after a while. */ while (sleep (10) != 0) ; diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index 8c3cabbd11..01e6f41f20 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008 Apple, Inc. * Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -120,6 +121,8 @@ enum { kXquartzWindowMoved, // window has moved on screen }; +void DarwinSendDDXEvent(int type, int argc, ...); + #define ENABLE_DEBUG_LOG 1 #ifdef ENABLE_DEBUG_LOG diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 28a712dabb..b6cd3f2b09 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -476,3 +476,31 @@ void DarwinUpdateModKeys(int flags) { DarwinUpdateModifiers(KeyPress, ~old_flags & flags); old_flags = flags; } + + +/* + * DarwinSendDDXEvent + * Send the X server thread a message by placing it on the event queue. + */ +void DarwinSendDDXEvent(int type, int argc, ...) { + xEvent xe; + INT32 *argv; + int i, max_args; + va_list args; + + memset(&xe, 0, sizeof(xe)); + xe.u.u.type = type; + xe.u.clientMessage.u.l.type = type; + + argv = &xe.u.clientMessage.u.l.longs0; + max_args = 4; + + if (argc > 0 && argc <= max_args) { + va_start (args, argc); + for (i = 0; i < argc; i++) + argv[i] = (int) va_arg (args, int); + va_end (args); + } + + mieqEnqueue(NULL, &xe); +} diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h index 1d8e92a7b1..7c56be9c83 100644 --- a/hw/xquartz/darwinEvents.h +++ b/hw/xquartz/darwinEvents.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2008 Apple, Inc. * Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -43,4 +44,5 @@ void DarwinUpdateModKeys(int flags); void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents); + #endif /* _DARWIN_EVENTS_H */ diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index a65bd37486..96dc021a63 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -373,34 +373,3 @@ void QuartzSpaceChanged(uint32_t space_id) { /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id); } - -/* - * QuartzMessageServerThread - * Send the X server thread a message by placing it on the event queue. - */ -void -QuartzMessageServerThread( - int type, - int argc, ...) -{ - xEvent xe; - INT32 *argv; - int i, max_args; - va_list args; - - memset(&xe, 0, sizeof(xe)); - xe.u.u.type = type; - xe.u.clientMessage.u.l.type = type; - - argv = &xe.u.clientMessage.u.l.longs0; - max_args = 4; - - if (argc > 0 && argc <= max_args) { - va_start (args, argc); - for (i = 0; i < argc; i++) - argv[i] = (int) va_arg (args, int); - va_end (args); - } - - mieqEnqueue(NULL, &xe); -} diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index 5e144731d9..91bf25ac2d 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -68,7 +68,7 @@ static void eventHandler(unsigned int type, const void *arg, switch (type) { case XP_EVENT_DISPLAY_CHANGED: DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n"); - QuartzMessageServerThread(kXquartzDisplayChanged, 0); + DarwinSendDDXEvent(kXquartzDisplayChanged, 0); break; case XP_EVENT_WINDOW_STATE_CHANGED: @@ -76,7 +76,7 @@ static void eventHandler(unsigned int type, const void *arg, const xp_window_state_event *ws_arg = arg; DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n", ws_arg->id, ws_arg->state); - QuartzMessageServerThread(kXquartzWindowState, 2, + DarwinSendDDXEvent(kXquartzWindowState, 2, ws_arg->id, ws_arg->state); } else { DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n"); @@ -88,7 +88,7 @@ static void eventHandler(unsigned int type, const void *arg, if (arg_size == sizeof(xp_window_id)) { xp_window_id id = * (xp_window_id *) arg; WindowPtr pWin = xprGetXWindow(id); - QuartzMessageServerThread(kXquartzWindowMoved, 1, pWin); + DarwinSendDDXEvent(kXquartzWindowMoved, 1, pWin); } break; @@ -111,7 +111,7 @@ static void eventHandler(unsigned int type, const void *arg, ErrorF("XP_EVENT_SPACE_CHANGED\n"); if(arg_size == sizeof(uint32_t)) { uint32_t space_id = *(uint32_t *)arg; - QuartzMessageServerThread(kXquartzSpaceChanged, 1, space_id); + DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id); } break; default: From 15b0084f1ab23042190d8beeb3f088b92dee5a10 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 23:31:25 -0700 Subject: [PATCH 26/34] formatting cleanup for X11Application.m (no code changes) (cherry picked from commit eb083d3f68f459d90417558da1ed00729b749950) --- hw/xquartz/X11Application.m | 493 +++++++++++++++++------------------- 1 file changed, 237 insertions(+), 256 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 28bb529951..2844fca105 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -166,171 +166,170 @@ static void message_kit_thread (SEL selector, NSObject *arg) { static TSMDocumentID x11_document; DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active) if (state) { - DarwinSendDDXEvent(kXquartzActivate, 0); - - if (!_x_active) { - if (x11_document == 0 && darwinKeymapFile == NULL) { - OSType types[1]; - types[0] = kUnicodeDocument; - NewTSMDocument (1, types, &x11_document, 0); - } - - if (x11_document != 0) ActivateTSMDocument (x11_document); - } + DarwinSendDDXEvent(kXquartzActivate, 0); + + if (!_x_active) { + if (x11_document == 0 && darwinKeymapFile == NULL) { + OSType types[1]; + types[0] = kUnicodeDocument; + NewTSMDocument (1, types, &x11_document, 0); + } + + if (x11_document != 0) ActivateTSMDocument (x11_document); + } } else { - DarwinSendDDXEvent(kXquartzDeactivate, 0); - - if (_x_active && x11_document != 0) - DeactivateTSMDocument (x11_document); - } - - _x_active = state; + DarwinSendDDXEvent(kXquartzDeactivate, 0); + + if (_x_active && x11_document != 0) + DeactivateTSMDocument (x11_document); + } + + _x_active = state; } - (void) became_key:(NSWindow *)win { - [self activateX:NO]; + [self activateX:NO]; } - (void) sendEvent:(NSEvent *)e { - NSEventType type; - BOOL for_appkit, for_x; + NSEventType type; + BOOL for_appkit, for_x; + + type = [e type]; + + /* By default pass down the responder chain and to X. */ + for_appkit = YES; + for_x = YES; - type = [e type]; - - /* By default pass down the responder chain and to X. */ - for_appkit = YES; - for_x = YES; - - switch (type) { - case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: - case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: - if ([e window] != nil) { - /* Pointer event has an (AppKit) window. Probably something for the kit. */ - for_x = NO; - if (_x_active) [self activateX:NO]; - } else if ([self modalWindow] == nil) { - /* Must be an X window. Tell appkit it doesn't have focus. */ - WindowPtr pWin = xprGetXWindowFromAppKit([e windowNumber]); - if (pWin) RootlessReorderWindow(pWin); - for_appkit = NO; - - if ([self isActive]) { - [self deactivate]; - - if (!_x_active && quartzProcs->IsX11Window([e window], - [e windowNumber])) - [self activateX:YES]; - } - } - break; - - case NSKeyDown: case NSKeyUp: - if (_x_active) { - static int swallow_up; - - /* No kit window is focused, so send it to X. */ - for_appkit = NO; - if (type == NSKeyDown) { - /* Before that though, see if there are any global - shortcuts bound to it. */ - - if (X11EnableKeyEquivalents - && [[self mainMenu] performKeyEquivalent:e]) { - swallow_up = [e keyCode]; - for_x = NO; - } else if (!quartzEnableRootless - && ([e modifierFlags] & ALL_KEY_MASKS) - == (NSCommandKeyMask | NSAlternateKeyMask) - && ([e keyCode] == 0 /*a*/ - || [e keyCode] == 53 /*Esc*/)) { - swallow_up = 0; - for_x = NO; + switch (type) { + case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: + case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: + if ([e window] != nil) { + /* Pointer event has an (AppKit) window. Probably something for the kit. */ + for_x = NO; + if (_x_active) [self activateX:NO]; + } else if ([self modalWindow] == nil) { + /* Must be an X window. Tell appkit it doesn't have focus. */ + WindowPtr pWin = xprGetXWindowFromAppKit([e windowNumber]); + if (pWin) RootlessReorderWindow(pWin); + for_appkit = NO; + + if ([self isActive]) { + [self deactivate]; + if (!_x_active && quartzProcs->IsX11Window([e window], + [e windowNumber])) + [self activateX:YES]; + } + } + break; + + case NSKeyDown: case NSKeyUp: + if (_x_active) { + static int swallow_up; + + /* No kit window is focused, so send it to X. */ + for_appkit = NO; + if (type == NSKeyDown) { + /* Before that though, see if there are any global + shortcuts bound to it. */ + + if (X11EnableKeyEquivalents + && [[self mainMenu] performKeyEquivalent:e]) { + swallow_up = [e keyCode]; + for_x = NO; + } else if (!quartzEnableRootless + && ([e modifierFlags] & ALL_KEY_MASKS) + == (NSCommandKeyMask | NSAlternateKeyMask) + && ([e keyCode] == 0 /*a*/ + || [e keyCode] == 53 /*Esc*/)) { + swallow_up = 0; + for_x = NO; #ifdef DARWIN_DDX_MISSING - DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); #endif + } + } else { + /* If we saw a key equivalent on the down, don't pass + the up through to X. */ + + if (swallow_up != 0 && [e keyCode] == swallow_up) { + swallow_up = 0; + for_x = NO; + } + } + } else for_x = NO; + break; + + case NSFlagsChanged: + /* For the l33t X users who remap modifier keys to normal keysyms. */ + if (!_x_active) for_x = NO; + break; + + case NSAppKitDefined: + switch ([e subtype]) { + case NSApplicationActivatedEventType: + for_x = NO; + if ([self modalWindow] == nil) { + for_appkit = NO; + + /* FIXME: hack to avoid having to pass the event to appkit, + which would cause it to raise one of its windows. */ + _appFlags._active = YES; + + [self activateX:YES]; + if ([e data2] & 0x10) X11ApplicationSetFrontProcess(); + } + break; + + case 18: /* ApplicationDidReactivate */ + if (quartzHasRoot) for_appkit = NO; + break; + + case NSApplicationDeactivatedEventType: + for_x = NO; + [self activateX:NO]; + break; + } + break; + + default: break; /* for gcc */ } - } else { - /* If we saw a key equivalent on the down, don't pass - the up through to X. */ - - if (swallow_up != 0 && [e keyCode] == swallow_up) { - swallow_up = 0; - for_x = NO; - } - } - } else for_x = NO; - break; - - case NSFlagsChanged: - /* For the l33t X users who remap modifier keys to normal keysyms. */ - if (!_x_active) for_x = NO; - break; - - case NSAppKitDefined: - switch ([e subtype]) { - case NSApplicationActivatedEventType: - for_x = NO; - if ([self modalWindow] == nil) { - for_appkit = NO; - - /* FIXME: hack to avoid having to pass the event to appkit, - which would cause it to raise one of its windows. */ - _appFlags._active = YES; - - [self activateX:YES]; - if ([e data2] & 0x10) X11ApplicationSetFrontProcess(); - } - break; - - case 18: /* ApplicationDidReactivate */ - if (quartzHasRoot) for_appkit = NO; - break; - - case NSApplicationDeactivatedEventType: - for_x = NO; - [self activateX:NO]; - break; - } - break; - - default: break; /* for gcc */ - } - - if (for_appkit) [super sendEvent:e]; - - if (for_x) send_nsevent (type, e); + + if (for_appkit) [super sendEvent:e]; + + if (for_x) send_nsevent (type, e); } - (void) set_window_menu:(NSArray *)list { - [_controller set_window_menu:list]; + [_controller set_window_menu:list]; } - (void) set_window_menu_check:(NSNumber *)n { - [_controller set_window_menu_check:n]; + [_controller set_window_menu_check:n]; } - (void) set_apps_menu:(NSArray *)list { - [_controller set_apps_menu:list]; + [_controller set_apps_menu:list]; } - (void) set_front_process:unused { - [NSApp activateIgnoringOtherApps:YES]; + [NSApp activateIgnoringOtherApps:YES]; - if ([self modalWindow] == nil) - [self activateX:YES]; + if ([self modalWindow] == nil) + [self activateX:YES]; } - (void) set_can_quit:(NSNumber *)state { - [_controller set_can_quit:[state boolValue]]; + [_controller set_can_quit:[state boolValue]]; } - (void) server_ready:unused { - [_controller server_ready]; + [_controller server_ready]; } - (void) show_hide_menubar:(NSNumber *)state { - if ([state boolValue]) ShowMenuBar (); - else HideMenuBar (); + if ([state boolValue]) ShowMenuBar (); + else HideMenuBar (); } @@ -348,57 +347,57 @@ static void cfrelease (CFAllocatorRef a, const void *b) { } static CFMutableArrayRef nsarray_to_cfarray (NSArray *in) { - CFMutableArrayRef out; - CFArrayCallBacks cb; - NSObject *ns; - const CFTypeRef *cf; - int i, count; - - memset (&cb, 0, sizeof (cb)); - cb.version = 0; - cb.retain = cfretain; - cb.release = cfrelease; - - count = [in count]; - out = CFArrayCreateMutable (NULL, count, &cb); - - for (i = 0; i < count; i++) { - ns = [in objectAtIndex:i]; - - if ([ns isKindOfClass:[NSArray class]]) - cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns); - else - cf = CFRetain ((CFTypeRef) ns); - - CFArrayAppendValue (out, cf); - CFRelease (cf); - } - - return out; + CFMutableArrayRef out; + CFArrayCallBacks cb; + NSObject *ns; + const CFTypeRef *cf; + int i, count; + + memset (&cb, 0, sizeof (cb)); + cb.version = 0; + cb.retain = cfretain; + cb.release = cfrelease; + + count = [in count]; + out = CFArrayCreateMutable (NULL, count, &cb); + + for (i = 0; i < count; i++) { + ns = [in objectAtIndex:i]; + + if ([ns isKindOfClass:[NSArray class]]) + cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns); + else + cf = CFRetain ((CFTypeRef) ns); + + CFArrayAppendValue (out, cf); + CFRelease (cf); + } + + return out; } static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { - NSMutableArray *out; - const CFTypeRef *cf; - NSObject *ns; - int i, count; - - count = CFArrayGetCount (in); - out = [[NSMutableArray alloc] initWithCapacity:count]; - - for (i = 0; i < count; i++) { - cf = CFArrayGetValueAtIndex (in, i); - - if (CFGetTypeID (cf) == CFArrayGetTypeID ()) - ns = cfarray_to_nsarray ((CFArrayRef) cf); - else - ns = [(id)cf retain]; - - [out addObject:ns]; - [ns release]; - } - - return out; + NSMutableArray *out; + const CFTypeRef *cf; + NSObject *ns; + int i, count; + + count = CFArrayGetCount (in); + out = [[NSMutableArray alloc] initWithCapacity:count]; + + for (i = 0; i < count; i++) { + cf = CFArrayGetValueAtIndex (in, i); + + if (CFGetTypeID (cf) == CFArrayGetTypeID ()) + ns = cfarray_to_nsarray ((CFArrayRef) cf); + else + ns = [(id)cf retain]; + + [out addObject:ns]; + [ns release]; + } + + return out; } - (CFPropertyListRef) prefs_get:(NSString *)key { @@ -855,86 +854,68 @@ convert_flags (unsigned int nsflags) { return xflags; } - -// This code should probably be merged with that in XDarwin's XServer.m - BB static void send_nsevent (NSEventType type, NSEvent *e) { - // static unsigned int button_state = 0; - NSRect screen; - NSPoint location; - NSWindow *window; - int pointer_x, pointer_y, ev_button, ev_type; - float pressure, tilt_x, tilt_y; + NSRect screen; + NSPoint location; + NSWindow *window; + int pointer_x, pointer_y, ev_button, ev_type; + float pressure, tilt_x, tilt_y; + + /* convert location to global top-left coordinates */ + location = [e locationInWindow]; + window = [e window]; + screen = [[[NSScreen screens] objectAtIndex:0] frame]; - // int num_events=0, i=0, state; - // xEvent xe; - - /* convert location to global top-left coordinates */ - location = [e locationInWindow]; - window = [e window]; - screen = [[[NSScreen screens] objectAtIndex:0] frame]; - if (window != nil) { - NSRect frame = [window frame]; - pointer_x = location.x + frame.origin.x; - pointer_y = (((screen.origin.y + screen.size.height) - - location.y) - frame.origin.y); - } else { - pointer_x = location.x; - pointer_y = (screen.origin.y + screen.size.height) - location.y; - } - - pointer_y -= aquaMenuBarHeight; - // state = convert_flags ([e modifierFlags]); - - pressure = 0; // for tablets - tilt_x = 0; - tilt_y = 0; - - switch (type) { - case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse; - case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse; - case NSRightMouseDown: ev_button=3; ev_type=ButtonPress; goto handle_mouse; - case NSLeftMouseUp: ev_button=1; ev_type=ButtonRelease; goto handle_mouse; - case NSOtherMouseUp: ev_button=2; ev_type=ButtonRelease; goto handle_mouse; - case NSRightMouseUp: ev_button=3; ev_type=ButtonRelease; goto handle_mouse; - case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; - case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; - case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse; - case NSTabletPoint: - pressure = [e pressure]; - tilt_x = [e tilt].x; - tilt_y = [e tilt].y; // fall through - case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse; - handle_mouse: - - /* I'm not sure the below code is necessary or useful (-bb) - if(ev_type==ButtonPress) { - if (!quartzProcs->IsX11Window([e window], [e windowNumber])) { - fprintf(stderr, "Dropping event because it's not a window\n"); - break; + NSRect frame = [window frame]; + pointer_x = location.x + frame.origin.x; + pointer_y = (((screen.origin.y + screen.size.height) + - location.y) - frame.origin.y); + } else { + pointer_x = location.x; + pointer_y = (screen.origin.y + screen.size.height) - location.y; } - button_state |= (1 << ev_button); - DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y); - } else if (ev_type==ButtonRelease && (button_state & (1 << ev_button)) == 0) break; - */ - // if ([e subtype] == NSTabletPointEventSubtype) pressure = [e pressure]; - DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y, - pressure, tilt_x, tilt_y); - break; - case NSScrollWheel: - DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y, - pressure, tilt_x, tilt_y); - break; - - case NSKeyDown: // do we need to translate these keyCodes? - case NSKeyUp: - DarwinSendKeyboardEvents((type == NSKeyDown)?KeyPress:KeyRelease, [e keyCode]); - break; + pointer_y -= aquaMenuBarHeight; - case NSFlagsChanged: - DarwinUpdateModKeys([e modifierFlags]); - break; - default: break; /* for gcc */ - } + pressure = 0; // for tablets + tilt_x = 0; + tilt_y = 0; + + switch (type) { + case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse; + case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse; + case NSRightMouseDown: ev_button=3; ev_type=ButtonPress; goto handle_mouse; + case NSLeftMouseUp: ev_button=1; ev_type=ButtonRelease; goto handle_mouse; + case NSOtherMouseUp: ev_button=2; ev_type=ButtonRelease; goto handle_mouse; + case NSRightMouseUp: ev_button=3; ev_type=ButtonRelease; goto handle_mouse; + case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; + case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; + case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse; + case NSTabletPoint: + pressure = [e pressure]; + tilt_x = [e tilt].x; + tilt_y = [e tilt].y; // fall through + case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse; + handle_mouse: + +// if ([e subtype] == NSTabletPointEventSubtype) pressure = [e pressure]; + DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); + break; + + case NSScrollWheel: + DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y, + pressure, tilt_x, tilt_y); + break; + + case NSKeyDown: case NSKeyUp: + DarwinSendKeyboardEvents((type == NSKeyDown)?KeyPress:KeyRelease, [e keyCode]); + break; + + case NSFlagsChanged: + DarwinUpdateModKeys([e modifierFlags]); + break; + default: break; /* for gcc */ + } } From c737d04c758e03e32f692a31ed2a665ccbafa931 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Tue, 1 Apr 2008 00:40:46 -0700 Subject: [PATCH 27/34] The AppKit thread should not be calling directly into the X server functions to change state when the keyboard is reloaded; instead, pass it as an event. (cherry picked from commit 7e653f806ff5508aace059312156f319a9ed4479) --- hw/xquartz/darwin.h | 7 +------ hw/xquartz/darwinEvents.c | 7 ++++--- hw/xquartz/darwinKeyboard.c | 12 +++++++----- hw/xquartz/darwinKeyboard.h | 2 +- hw/xquartz/quartzKeyboard.h | 1 - 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index 01e6f41f20..df92d8b494 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -91,13 +91,8 @@ extern int darwinMainScreenY; * Special ddx events understood by the X server */ enum { - kXquartzUpdateModifiers // update all modifier keys + kXquartzReloadKeymap // Reload system keymap = LASTEvent+1, // (from X.h list of event names) - kXquartzUpdateButtons, // update state of mouse buttons 2 and up - kXquartzScrollWheel, // scroll wheel event - /* - * Quartz-specific events -- not used in IOKit mode - */ kXquartzActivate, // restore X drawing and cursor kXquartzDeactivate, // clip X drawing and switch to Aqua cursor kXquartzSetRootClip, // enable or disable drawing to the X screen diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index b6cd3f2b09..3afbaf890c 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -289,6 +289,7 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { FatalError("Couldn't allocate event buffer\n"); mieqInit(); + mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler); mieqSetHandler(kXquartzActivate, DarwinEventHandler); mieqSetHandler(kXquartzDeactivate, DarwinEventHandler); mieqSetHandler(kXquartzSetRootClip, DarwinEventHandler); @@ -322,7 +323,7 @@ void ProcessInputEvents(void) { // Empty the signaling pipe int x = sizeof(xe); while (x == sizeof(xe)) { - DEBUG_LOG("draining pipe\n"); +// DEBUG_LOG("draining pipe\n"); x = read(darwinEventReadFD, &xe, sizeof(xe)); } } @@ -412,8 +413,8 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) { this_seed = QuartzSystemKeymapSeed(); if (this_seed != last_seed) { - last_seed = this_seed; - DarwinKeyboardReload(darwinKeyboard); + last_seed = this_seed; + DarwinSendDDXEvent(kXquartzReloadKeymap, 0); } } diff --git a/hw/xquartz/darwinKeyboard.c b/hw/xquartz/darwinKeyboard.c index 355d9f066e..6f2758e534 100644 --- a/hw/xquartz/darwinKeyboard.c +++ b/hw/xquartz/darwinKeyboard.c @@ -850,16 +850,18 @@ static Bool InitModMap(register KeyClassPtr keyc) { } -void DarwinKeyboardReload(DeviceIntPtr pDev) { +void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { KeySymsRec keySyms; - + if (dev == NULL) dev = darwinKeyboard; + + DEBUG_LOG("DarwinKeyboardReloadHandler(%p)\n", dev); DarwinLoadKeyboardMapping(&keySyms); - if (SetKeySymsMap(&pDev->key->curKeySyms, &keySyms)) { + if (SetKeySymsMap(&dev->key->curKeySyms, &keySyms)) { /* now try to update modifiers. */ - memmove(pDev->key->modifierMap, keyInfo.modMap, MAP_LENGTH); - InitModMap(pDev->key); + memmove(dev->key->modifierMap, keyInfo.modMap, MAP_LENGTH); + InitModMap(dev->key); } else DEBUG_LOG("SetKeySymsMap=0\n"); SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0); diff --git a/hw/xquartz/darwinKeyboard.h b/hw/xquartz/darwinKeyboard.h index 5cf64c7d11..762f659190 100644 --- a/hw/xquartz/darwinKeyboard.h +++ b/hw/xquartz/darwinKeyboard.h @@ -31,7 +31,7 @@ /* Provided for darwinEvents.c */ extern darwinKeyboardInfo keyInfo; -void DarwinKeyboardReload(DeviceIntPtr pDev); +void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents); void DarwinKeyboardInit(DeviceIntPtr pDev); int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide); int DarwinModifierNXKeyToNXKeycode(int key, int side); diff --git a/hw/xquartz/quartzKeyboard.h b/hw/xquartz/quartzKeyboard.h index 8131b56504..4f495bb463 100644 --- a/hw/xquartz/quartzKeyboard.h +++ b/hw/xquartz/quartzKeyboard.h @@ -46,7 +46,6 @@ typedef struct darwinKeyboardInfo_struct { } darwinKeyboardInfo; /* These functions need to be implemented by Xquartz, XDarwin, etc. */ -void DarwinKeyboardReload(DeviceIntPtr pDev); Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info); unsigned int QuartzSystemKeymapSeed(void); From 2e42b67b82db0f9128dd00e339b9dfdd9fe6d667 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 18:05:34 -0700 Subject: [PATCH 28/34] XQuartz: Change reporting of space change to debug log rather than stderr (cherry picked from commit ed15556a9fc4ebdb88f42961052fc8456082165f) --- hw/xquartz/xpr/xprScreen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index 91bf25ac2d..d685fca332 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -108,7 +108,7 @@ static void eventHandler(unsigned int type, const void *arg, } break; case XP_EVENT_SPACE_CHANGED: - ErrorF("XP_EVENT_SPACE_CHANGED\n"); + DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n"); if(arg_size == sizeof(uint32_t)) { uint32_t space_id = *(uint32_t *)arg; DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id); From f0915fb3c4a9712200882440a64d11dc595a02bb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Apr 2008 09:29:51 +1000 Subject: [PATCH 29/34] quirk: add quirk for ACER EDID --- hw/xfree86/modes/xf86EdidModes.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index f15c39642b..8f7d45dd62 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -158,6 +158,11 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC) DDC->vendor.prod_id == 765) return TRUE; + /* ACR of some sort RH #284231 */ + if (memcmp (DDC->vendor.name, "ACR", 4) == 0 && + DDC->vendor.prod_id == 2423) + return TRUE; + return FALSE; } From 16a8ce75585ea360c39e0ffce4f7bb26a359b754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 3 Apr 2008 16:44:32 -0400 Subject: [PATCH 30/34] Only autoload RECORD if it was enabled. --- hw/xfree86/common/xf86Config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 8de7426207..208e23dc4d 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -119,7 +119,9 @@ static ModuleDefault ModuleDefaults[] = { {.name = "dbe", .toLoad = TRUE, .load_opt=NULL}, {.name = "glx", .toLoad = TRUE, .load_opt=NULL}, {.name = "freetype", .toLoad = TRUE, .load_opt=NULL}, +#ifdef XRECORD {.name = "record", .toLoad = TRUE, .load_opt=NULL}, +#endif {.name = "dri", .toLoad = TRUE, .load_opt=NULL}, {.name = "dri2", .toLoad = TRUE, .load_opt=NULL}, {.name = NULL, .toLoad = FALSE, .load_opt=NULL} From ec17900f52bbd25d07566834756e5c7e832e0463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 4 Apr 2008 10:46:45 -0400 Subject: [PATCH 31/34] Convert __DRIconfigs after we've made sure createNewScreen succeeded. --- GL/glx/glxdri.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index ffa9a0b766..9cd0738a0e 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -1117,13 +1117,13 @@ __glXDRIscreenProbe(ScreenPtr pScreen) &driConfigs, screen); - screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); - if (screen->driScreen == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); goto handle_error; } + screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); + initializeExtensions(screen); DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart, From d1de3dda8efe501d4192c8a99c34ab4265316c32 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 17 Mar 2008 14:22:39 -0700 Subject: [PATCH 32/34] Fix clock_gettime presence detect on FreeBSD. For non-Linux, _POSIX_C_SOURCE and friends restrict symbols defined rather than enabling defines of symbols. Additionally, CLOCK_MONOTONIC was apparently added to the standard around 2000 anyway, not 1993. --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index 985c8e2272..1431f4b8f5 100644 --- a/configure.ac +++ b/configure.ac @@ -722,7 +722,9 @@ if ! test "x$have_clock_gettime" = xno; then LIBS="$CLOCK_LIBS" AC_RUN_IFELSE([ +#ifdef __linux__ #define _POSIX_C_SOURCE 199309L +#endif #include int main(int argc, char *argv[[]]) { From cc7c045bae01d90d8f1b750080ba48a96e983c68 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 4 Apr 2008 12:58:12 -0400 Subject: [PATCH 33/34] Fix PCI config space cycles from int10 emulator. The top bit of 0xCF8 is an enable bit, not part of the domain. Sending cycles to domain 128 instead of domain 0 is rarely the right thing to do. --- hw/xfree86/int10/helper_exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c index 9daff22dcf..c3af5bc08d 100644 --- a/hw/xfree86/int10/helper_exec.c +++ b/hw/xfree86/int10/helper_exec.c @@ -461,7 +461,7 @@ Mem_wl(CARD32 addr, CARD32 val) static CARD32 PciCfg1Addr = 0; #define PCI_OFFSET(x) ((x) & 0x000000ff) -#define PCI_TAG(x) ((x) & 0xffffff00) +#define PCI_TAG(x) ((x) & 0x7fffff00) static struct pci_device* pci_device_for_cfg_address (CARD32 addr) From 6c0cfe3d43b177c4cfaf7e228f32c655f9a98459 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Fri, 4 Apr 2008 19:01:40 +0200 Subject: [PATCH 34/34] Fix the clock_gettime check for glibc-based non-Linux systems We need to define _POSIX_C_SOURCE on glibc, not just Linux, so add a new test for the __GLIBC__ macro. --- configure.ac | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 1431f4b8f5..025b91214c 100644 --- a/configure.ac +++ b/configure.ac @@ -705,6 +705,15 @@ if test "x$NEED_DBUS" = xyes; then fi CONFIG_LIB='$(top_builddir)/config/libconfig.a' +AC_MSG_CHECKING([for glibc...]) +AC_PREPROC_IFELSE([ +#include +#ifndef __GLIBC__ +#error +#endif +], glibc=yes, glibc=no) +AC_MSG_RESULT([$glibc]) + AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt], [have_clock_gettime=no])]) @@ -720,11 +729,13 @@ if ! test "x$have_clock_gettime" = xno; then LIBS_SAVE="$LIBS" LIBS="$CLOCK_LIBS" + CPPFLAGS_SAVE="$CPPFLAGS" + + if test x"$glibc" = xyes; then + CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=199309L" + fi AC_RUN_IFELSE([ -#ifdef __linux__ -#define _POSIX_C_SOURCE 199309L -#endif #include int main(int argc, char *argv[[]]) { @@ -739,6 +750,7 @@ int main(int argc, char *argv[[]]) { [MONOTONIC_CLOCK="cross compiling"]) LIBS="$LIBS_SAVE" + CPPFLAGS="$CPPFLAGS_SAVE" else MONOTONIC_CLOCK=no fi