From a7971771a8ab6f6f76a2a8e482dbb3a30901af1c Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 25 Feb 2011 07:31:13 +0000 Subject: xserver randrproto mesa xkeyboard-config git update 25 Feb 2011 --- xorg-server/hw/dmx/glxProxy/glxcmds.c | 7302 ++++++++++--------- xorg-server/hw/dmx/glxProxy/glxsingle.c | 2031 +++--- xorg-server/hw/dmx/glxProxy/glxvendor.c | 1170 ++-- xorg-server/hw/dmx/glxProxy/render2swap.c | 626 +- xorg-server/hw/xfree86/common/xf86Helper.c | 4100 ++++++----- xorg-server/hw/xfree86/common/xf86Module.h | 2 +- xorg-server/hw/xfree86/common/xf86sbusBus.c | 1428 ++-- xorg-server/hw/xfree86/modes/xf86Crtc.c | 6523 +++++++++-------- xorg-server/hw/xfree86/modes/xf86Crtc.h | 2047 +++--- xorg-server/hw/xfree86/modes/xf86Cursors.c | 1376 ++-- xorg-server/hw/xfree86/modes/xf86RandR12.c | 3831 +++++----- xorg-server/hw/xfree86/modes/xf86Rotate.c | 1090 ++- xorg-server/hw/xfree86/os-support/bsd/bsd_init.c | 1516 ++-- xorg-server/hw/xfree86/os-support/xf86_OSlib.h | 8 - xorg-server/hw/xquartz/bundle/Info.plist.cpp | 2 + .../bundle/Resources/French.lproj/locversion.plist | 28 +- .../Resources/French.lproj/main.nib/designable.nib | 7383 ++++++++++---------- .../French.lproj/main.nib/keyedobjects.nib | Bin 55820 -> 36464 bytes .../bundle/Resources/German.lproj/locversion.plist | 4 +- .../Resources/German.lproj/main.nib/designable.nib | 360 +- .../German.lproj/main.nib/keyedobjects.nib | Bin 52574 -> 35590 bytes .../Resources/Japanese.lproj/locversion.plist | 4 +- .../Japanese.lproj/main.nib/designable.nib | 323 +- .../Japanese.lproj/main.nib/keyedobjects.nib | Bin 46474 -> 33650 bytes 24 files changed, 20656 insertions(+), 20498 deletions(-) (limited to 'xorg-server/hw') diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.c b/xorg-server/hw/dmx/glxProxy/glxcmds.c index 74af631ad..f79264ea9 100644 --- a/xorg-server/hw/dmx/glxProxy/glxcmds.c +++ b/xorg-server/hw/dmx/glxProxy/glxcmds.c @@ -1,3657 +1,3645 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 - * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifdef HAVE_DMX_CONFIG_H -#include -#endif - -#include "dmx.h" -#include "dmxwindow.h" -#include "dmxpixmap.h" -#include "dmxfont.h" -#include "dmxsync.h" - -#include "glxserver.h" -#include -#include "g_disptab.h" -#include -#include -#include "glxutil.h" -#include "glxext.h" -#include "unpack.h" - -#include "GL/glxproto.h" -#include "glxvendor.h" -#include "glxvisuals.h" -#include "glxswap.h" - -#ifdef PANORAMIX -#include "panoramiXsrv.h" -#endif - -extern __GLXFBConfig **__glXFBConfigs; -extern int __glXNumFBConfigs; - -extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id ); -extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid ); -extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen ); -extern int glxIsExtensionSupported( char *ext ); -extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); - -#define BE_TO_CLIENT_ERROR(x) \ - ( (x) >= __glXerrorBase ? \ - (x) - dmxScreen->glxErrorBase + __glXerrorBase \ - : (x) ) - -Display *GetBackEndDisplay( __GLXclientState *cl, int s ) -{ - if (! cl->be_displays[s] ) { - cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) ); - } - return cl->be_displays[s]; -} - -/* -** Create a GL context with the given properties. -*/ -static int CreateContext(__GLXclientState *cl, - GLXContextID gcId, - VisualID vid, GLXFBConfigID fbconfigId, - int screen, - GLXContextID shareList, - int isDirect ) -{ - ClientPtr client = cl->client; - xGLXCreateContextReq *be_req; - xGLXCreateNewContextReq *be_new_req; - VisualPtr pVisual; - ScreenPtr pScreen; - __GLXcontext *glxc, *shareglxc; - __GLXvisualConfig *pGlxVisual; - __GLXscreenInfo *pGlxScreen; - VisualID visual = vid; - GLint i; - int from_screen = screen; - int to_screen = screen; - DMXScreenInfo *dmxScreen; - VisualID be_vid; - GLXFBConfigID be_fbconfigId; - int num_be_screens; - Display *dpy; - - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return BadValue; - } - - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - /* - ** Find the display list space that we want to share. - ** - */ - if (shareList == None) { - shareglxc = NULL; - } else { - dixLookupResourceByType((pointer*) &shareglxc, shareList, - __glXContextRes, NullClient, DixUnknownAccess); - if (!shareglxc) { - client->errorValue = shareList; - return __glXBadContext; - } - } - - /* - ** Allocate memory for the new context - */ - glxc = calloc(1, sizeof(__GLXcontext)); - if (!glxc) { - return BadAlloc; - } - - pScreen = screenInfo.screens[screen]; - pGlxScreen = &__glXActiveScreens[screen]; - - if (fbconfigId != None) { - glxc->pFBConfig = glxLookupFBConfig( fbconfigId ); - if (!glxc->pFBConfig) { - client->errorValue = fbconfigId; - free( glxc ); - return BadValue; - } - visual = glxc->pFBConfig->associatedVisualId; - } - else { - glxc->pFBConfig = NULL; - } - - if (visual != None) { - /* - ** Check if the visual ID is valid for this screen. - */ - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == visual) { - break; - } - } - if (i == pScreen->numVisuals) { - client->errorValue = visual; - free( glxc ); - return BadValue; - } - - pGlxVisual = pGlxScreen->pGlxVisual; - for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { - if (pGlxVisual->vid == visual) { - break; - } - } - if (i == pGlxScreen->numVisuals) { - /* - ** Visual not support on this screen by this OpenGL implementation. - */ - client->errorValue = visual; - free( glxc ); - return BadValue; - } - - if ( glxc->pFBConfig == NULL ) { - glxc->pFBConfig = glxLookupFBConfigByVID( visual ); - - if ( glxc->pFBConfig == NULL ) { - /* - * visual does not have an FBConfig ??? - client->errorValue = visual; - free( glxc ); - return BadValue; - */ - } - } - } - else { - pVisual = NULL; - pGlxVisual = NULL; - } - - glxc->pScreen = pScreen; - glxc->pGlxScreen = pGlxScreen; - glxc->pVisual = pVisual; - glxc->pGlxVisual = pGlxVisual; - - /* - * allocate memory for back-end servers info - */ - num_be_screens = to_screen - from_screen + 1; - glxc->real_ids = (XID *)malloc(sizeof(XID) * num_be_screens); - if (!glxc->real_ids) { - return BadAlloc; - } - glxc->real_vids = (XID *)malloc(sizeof(XID) * num_be_screens); - if (!glxc->real_vids) { - return BadAlloc; - } - - for (screen = from_screen; screen <= to_screen; screen++) { - int sent = 0; - pScreen = screenInfo.screens[screen]; - pGlxScreen = &__glXActiveScreens[screen]; - dmxScreen = &dmxScreens[screen]; - - if (glxc->pFBConfig) { - __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id, - screen ); - be_fbconfigId = beFBConfig->id; - } - - if (pGlxVisual) { - - be_vid = glxMatchGLXVisualInConfigList( pGlxVisual, - dmxScreen->glxVisuals, - dmxScreen->numGlxVisuals ); - - if (!be_vid) { - /* visual is not supported on the back-end server */ - free( glxc->real_ids ); - free( glxc->real_vids ); - free( glxc ); - return BadValue; - } - } - - glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen)); - - /* send the create context request to the back-end server */ - dpy = GetBackEndDisplay(cl,screen); - if (glxc->pFBConfig) { - /*Since for a certain visual both RGB and COLOR INDEX - *can be on then the only parmeter to choose the renderType - * should be the class of the colormap since all 4 first - * classes does not support RGB mode only COLOR INDEX , - * and so TrueColor and DirectColor does not support COLOR INDEX*/ - int renderType = glxc->pFBConfig->renderType; - if ( pVisual ) { - switch ( pVisual->class ){ - case PseudoColor: - case StaticColor: - case GrayScale: - case StaticGray: - renderType = GLX_COLOR_INDEX_TYPE; - break; - case TrueColor: - case DirectColor: - default: - renderType = GLX_RGBA_TYPE; - break; - } - } - if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { - LockDisplay(dpy); - GetReq(GLXCreateNewContext,be_new_req); - be_new_req->reqType = dmxScreen->glxMajorOpcode; - be_new_req->glxCode = X_GLXCreateNewContext; - be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; - be_new_req->fbconfig = (unsigned int)be_fbconfigId; - be_new_req->screen = DefaultScreen(dpy); - be_new_req->renderType = renderType; - - be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); - be_new_req->isDirect = 0; - UnlockDisplay(dpy); - glxc->real_vids[screen-from_screen] = be_fbconfigId; - sent = 1; - } - else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) { - - xGLXCreateContextWithConfigSGIXReq *ext_req; - xGLXVendorPrivateReq *vpreq; - LockDisplay(dpy); - GetReqExtra(GLXVendorPrivate, - sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq, - vpreq); - ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq; - ext_req->reqType = dmxScreen->glxMajorOpcode; - ext_req->glxCode = X_GLXVendorPrivate; - ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; - ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; - ext_req->fbconfig = (unsigned int)be_fbconfigId; - ext_req->screen = DefaultScreen(dpy); - ext_req->renderType = renderType; - ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); - ext_req->isDirect = 0; - UnlockDisplay(dpy); - glxc->real_vids[screen-from_screen] = be_fbconfigId; - sent = 1; - } - } - - if (!sent) { - LockDisplay(dpy); - GetReq(GLXCreateContext,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXCreateContext; - be_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; - be_req->visual = (unsigned int)be_vid; - be_req->screen = DefaultScreen(dpy); - be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); - be_req->isDirect = 0; - UnlockDisplay(dpy); - glxc->real_vids[screen-from_screen] = be_vid; - } - SyncHandle(); - - } - - /* - ** Register this context as a resource. - */ - if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { - free( glxc->real_ids ); - free( glxc->real_vids ); - free( glxc ); - client->errorValue = gcId; - return BadAlloc; - } - - /* - ** Finally, now that everything is working, setup the rest of the - ** context. - */ - glxc->id = gcId; - glxc->share_id = shareList; - glxc->idExists = GL_TRUE; - glxc->isCurrent = GL_FALSE; - - return Success; -} - -int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - - return( CreateContext(cl, req->context,req->visual, None, - req->screen, req->shareList, req->isDirect) ); - -} - -int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; - - return( CreateContext(cl, req->context,None, req->fbconfig, - req->screen, req->shareList, req->isDirect) ); - -} - -int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; - - return( CreateContext(cl, req->context, None, req->fbconfig, - req->screen, req->shareList, req->isDirect) ); - -} - -int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryMaxSwapBarriersSGIXReq *req = - (xGLXQueryMaxSwapBarriersSGIXReq *)pc; - xGLXQueryMaxSwapBarriersSGIXReply reply; - - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = 0; - reply.max = QueryMaxSwapBarriersSGIX(req->screen); - - if (client->swapped) { - __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply); - } else { - WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, - (char *)&reply); - } - - return Success; -} - -int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc; - DrawablePtr pDraw; - __GLXpixmap *pGlxPixmap = NULL; - __glXWindow *pGlxWindow = NULL; - int rc; - - rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess); - if (rc != Success) { - dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, - __glXPixmapRes, NullClient, DixUnknownAccess); - if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; - } - - if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, - __glXWindowRes, NullClient, DixUnknownAccess); - if (pGlxWindow) pDraw = pGlxWindow->pDraw; - } - - if (!pDraw) { - client->errorValue = req->drawable; - return __glXBadDrawable; - } - - return BindSwapBarrierSGIX(pDraw, req->barrier); -} - -int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc; - DrawablePtr pDraw, pMember = NULL; - __GLXpixmap *pGlxPixmap = NULL; - __glXWindow *pGlxWindow = NULL; - int rc; - - rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess); - if (rc != Success) { - dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, - __glXPixmapRes, NullClient, DixUnknownAccess); - if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; - } - - if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, - __glXWindowRes, NullClient, DixUnknownAccess); - if (pGlxWindow) pDraw = pGlxWindow->pDraw; - } - - if (!pDraw) { - client->errorValue = req->drawable; - return __glXBadDrawable; - } - - if (req->member != None) { - rc = dixLookupDrawable(&pMember, req->member, client, 0, - DixGetAttrAccess); - if (rc != Success) { - dixLookupResourceByType((pointer*) &pGlxPixmap, req->member, - __glXPixmapRes, NullClient, - DixUnknownAccess); - if (pGlxPixmap) pMember = pGlxPixmap->pDraw; - } - - if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxWindow, req->member, - __glXWindowRes, NullClient, - DixUnknownAccess); - if (pGlxWindow) pMember = pGlxWindow->pDraw; - } - - if (!pMember) { - client->errorValue = req->member; - return __glXBadDrawable; - } - } - - return JoinSwapGroupSGIX(pDraw, pMember); -} - - -/* -** Destroy a GL context as an X resource. -*/ -int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; - xGLXDestroyContextReq *be_req; - GLXContextID gcId = req->context; - __GLXcontext *glxc; - int from_screen = 0; - int to_screen = 0; - int s; - - dixLookupResourceByType((pointer*) &glxc, gcId, __glXContextRes, - NullClient, DixUnknownAccess); - if (glxc) { - /* - ** Just free the resource; don't actually destroy the context, - ** because it might be in use. The - ** destroy method will be called by the resource destruction routine - ** if necessary. - */ - FreeResourceByType(gcId, __glXContextRes, FALSE); - - from_screen = to_screen = glxc->pScreen->myNum; - - } else { - client->errorValue = gcId; - return __glXBadContext; - } - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - /* - * send DestroyContext request to all back-end servers - */ - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReq(GLXDestroyContext,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXDestroyContext; - be_req->context = glxc->real_ids[s-from_screen]; - UnlockDisplay(dpy); - SyncHandle(); - } - - return Success; -} - -/*****************************************************************************/ - -/* -** For each client, the server keeps a table of all the contexts that are -** current for that client (each thread of a client may have its own current -** context). These routines add, change, and lookup contexts in the table. -*/ - -/* -** Add a current context, and return the tag that will be used to refer to it. -*/ -static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw) -{ - int i; - int num = cl->numCurrentContexts; - __GLXcontext **table = cl->currentContexts; - - if (!glxc) return -1; - - /* - ** Try to find an empty slot and use it. - */ - for (i=0; i < num; i++) { - if (!table[i]) { - table[i] = glxc; - return i+1; - } - } - /* - ** Didn't find a free slot, so we'll have to grow the table. - */ - if (!num) { - table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); - cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr)); - cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens *sizeof(GLXContextTag)); - } else { - table = (__GLXcontext **) realloc(table, - (num+1)*sizeof(__GLXcontext *)); - cl->currentDrawables = (DrawablePtr *) realloc( - cl->currentDrawables , - (num+1)*sizeof(DrawablePtr)); - cl->be_currentCTag = (GLXContextTag *) realloc(cl->be_currentCTag, - (num+1)*screenInfo.numScreens*sizeof(GLXContextTag)); - } - table[num] = glxc; - cl->currentDrawables[num] = pDraw; - cl->currentContexts = table; - cl->numCurrentContexts++; - - memset(cl->be_currentCTag + num*screenInfo.numScreens, 0, - screenInfo.numScreens * sizeof(GLXContextTag)); - - return num+1; -} - -/* -** Given a tag, change the current context for the corresponding entry. -*/ -static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, - GLXContextTag tag) -{ - __GLXcontext **table = cl->currentContexts; - table[tag-1] = glxc; -} - -/* -** Given a tag, and back-end screen number, retrives the current back-end -** tag. -*/ -int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s) -{ - if (tag >0) { - return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] ); - } - else { - return 0; - } -} - -/* -** Given a tag, and back-end screen number, sets the current back-end -** tag. -*/ -static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag) -{ - if (tag >0) { - cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag; - } -} - -/* -** For this implementation we have chosen to simply use the index of the -** context's entry in the table as the context tag. A tag must be greater -** than 0. -*/ -__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) -{ - int num = cl->numCurrentContexts; - - if (tag < 1 || tag > num) { - return 0; - } else { - return cl->currentContexts[tag-1]; - } -} - -DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag) -{ - int num = cl->numCurrentContexts; - - if (tag < 1 || tag > num) { - return 0; - } else { - return cl->currentDrawables[tag-1]; - } -} - -/*****************************************************************************/ - -static void StopUsingContext(__GLXcontext *glxc) -{ - if (glxc) { - if (glxc == __glXLastContext) { - /* Tell server GL library */ - __glXLastContext = 0; - } - glxc->isCurrent = GL_FALSE; - if (!glxc->idExists) { - __glXFreeContext(glxc); - } - } -} - -static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) -{ - glxc->isCurrent = GL_TRUE; -} - -/*****************************************************************************/ -/* -** Make an OpenGL context and drawable current. -*/ -static int MakeCurrent(__GLXclientState *cl, - GLXDrawable drawable, - GLXDrawable readdrawable, - GLXContextID context, - GLXContextTag oldContextTag) -{ - ClientPtr client = cl->client; - DrawablePtr pDraw = NULL; - DrawablePtr pReadDraw = NULL; - xGLXMakeCurrentReadSGIReply new_reply; - xGLXMakeCurrentReq *be_req; - xGLXMakeCurrentReply be_reply; - xGLXMakeContextCurrentReq *be_new_req; - xGLXMakeContextCurrentReply be_new_reply; - GLXDrawable drawId = drawable; - GLXDrawable readId = readdrawable; - GLXContextID contextId = context; - __GLXpixmap *pGlxPixmap = 0; - __GLXpixmap *pReadGlxPixmap = 0; - __GLXcontext *glxc, *prevglxc; - GLXContextTag tag = oldContextTag; - WindowPtr pWin = NULL; - WindowPtr pReadWin = NULL; - __glXWindow *pGlxWindow = NULL; - __glXWindow *pGlxReadWindow = NULL; - __glXPbuffer *pGlxPbuffer = NULL; - __glXPbuffer *pGlxReadPbuffer = NULL; -#ifdef PANORAMIX - PanoramiXRes *pXinDraw = NULL; - PanoramiXRes *pXinReadDraw = NULL; -#endif - int from_screen = 0; - int to_screen = 0; - int s, rc; - - /* - ** If one is None and the other isn't, it's a bad match. - */ - if ((drawId == None && contextId != None) || - (drawId != None && contextId == None)) { - return BadMatch; - } - - /* - ** Lookup old context. If we have one, it must be in a usable state. - */ - if (tag != 0) { - prevglxc = __glXLookupContextByTag(cl, tag); - if (!prevglxc) { - /* - ** Tag for previous context is invalid. - */ - return __glXBadContextTag; - } - } else { - prevglxc = 0; - } - - /* - ** Lookup new context. It must not be current for someone else. - */ - if (contextId != None) { - dixLookupResourceByType((pointer*) &glxc, contextId, __glXContextRes, - NullClient, DixUnknownAccess); - if (!glxc) { - client->errorValue = contextId; - return __glXBadContext; - } - if ((glxc != prevglxc) && glxc->isCurrent) { - /* Context is current to somebody else */ - return BadAccess; - } - } else { - /* Switching to no context. Ignore new drawable. */ - glxc = 0; - } - - if (drawId != None) { - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); - if (rc == Success) { - if (pDraw->type == DRAWABLE_WINDOW) { - /* - ** Drawable is an X Window. - */ - VisualID vid; - pWin = (WindowPtr)pDraw; - vid = wVisual(pWin); - - new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); - new_reply.writeType = GLX_WINDOW_TYPE; - - /* - ** Check if window and context are similar. - */ - if ((vid != glxc->pVisual->vid) || - (pWin->drawable.pScreen != glxc->pScreen)) { - client->errorValue = drawId; - return BadMatch; - } - - from_screen = to_screen = pWin->drawable.pScreen->myNum; - - } else { - /* - ** An X Pixmap is not allowed as a parameter (a GLX Pixmap - ** is, but it must first be created with glxCreateGLXPixmap). - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - if (!pDraw) { - dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, - __glXPixmapRes, NullClient, - DixUnknownAccess); - if (pGlxPixmap) { - /* - ** Check if pixmap and context are similar. - */ - if (pGlxPixmap->pScreen != glxc->pScreen || - pGlxPixmap->pGlxVisual != glxc->pGlxVisual) { - client->errorValue = drawId; - return BadMatch; - } - pDraw = pGlxPixmap->pDraw; - - new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : - pGlxPixmap->pGlxVisual->vid); - - new_reply.writeType = GLX_PIXMAP_TYPE; - - from_screen = to_screen = pGlxPixmap->pScreen->myNum; - - } - } - - if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxWindow, drawId, - __glXWindowRes, NullClient, - DixUnknownAccess); - if (pGlxWindow) { - /* - ** Drawable is a GLXWindow. - ** - ** Check if GLX window and context are similar. - */ - if (pGlxWindow->pScreen != glxc->pScreen || - pGlxWindow->pGlxFBConfig != glxc->pFBConfig) { - client->errorValue = drawId; - return BadMatch; - } - - pDraw = pGlxWindow->pDraw; - new_reply.writeVid = pGlxWindow->pGlxFBConfig->id; - new_reply.writeType = GLX_GLXWINDOW_TYPE; - } - - } - - if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxPbuffer, drawId, - __glXPbufferRes, NullClient, - DixUnknownAccess); - if (pGlxPbuffer) { - if (pGlxPbuffer->pScreen != glxc->pScreen || - pGlxPbuffer->pFBConfig != glxc->pFBConfig) { - client->errorValue = drawId; - return BadMatch; - } - - pDraw = (DrawablePtr)pGlxPbuffer; - new_reply.writeVid = pGlxPbuffer->pFBConfig->id; - new_reply.writeType = GLX_PBUFFER_TYPE; - } - } - - if (!pDraw) { - /* - ** Drawable is not a Window , GLXWindow or a GLXPixmap. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - - } else { - pDraw = 0; - } - - if (readId != None && readId != drawId ) { - rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess); - if (rc == Success) { - if (pReadDraw->type == DRAWABLE_WINDOW) { - /* - ** Drawable is an X Window. - */ - VisualID vid; - pReadWin = (WindowPtr)pDraw; - vid = wVisual(pReadWin); - - new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); - new_reply.readType = GLX_WINDOW_TYPE; - - /* - ** Check if window and context are similar. - */ - if ((vid != glxc->pVisual->vid) || - (pReadWin->drawable.pScreen != glxc->pScreen)) { - client->errorValue = readId; - return BadMatch; - } - - } else { - - /* - ** An X Pixmap is not allowed as a parameter (a GLX Pixmap - ** is, but it must first be created with glxCreateGLXPixmap). - */ - client->errorValue = readId; - return __glXBadDrawable; - } - } - - if (!pReadDraw) { - dixLookupResourceByType((pointer*) &pReadGlxPixmap, readId, - __glXPixmapRes, NullClient, - DixUnknownAccess); - if (pReadGlxPixmap) { - /* - ** Check if pixmap and context are similar. - */ - if (pReadGlxPixmap->pScreen != glxc->pScreen || - pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) { - client->errorValue = readId; - return BadMatch; - } - pReadDraw = pReadGlxPixmap->pDraw; - - new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : - pReadGlxPixmap->pGlxVisual->vid ); - new_reply.readType = GLX_PIXMAP_TYPE; - - } - } - - if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxReadWindow, readId, - __glXWindowRes, NullClient, - DixUnknownAccess); - if (pGlxReadWindow) { - /* - ** Drawable is a GLXWindow. - ** - ** Check if GLX window and context are similar. - */ - if (pGlxReadWindow->pScreen != glxc->pScreen || - pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) { - client->errorValue = readId; - return BadMatch; - } - - pReadDraw = pGlxReadWindow->pDraw; - new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id; - new_reply.readType = GLX_GLXWINDOW_TYPE; - } - } - - if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxReadPbuffer, readId, - __glXPbufferRes, NullClient, - DixUnknownAccess); - if (pGlxReadPbuffer) { - if (pGlxReadPbuffer->pScreen != glxc->pScreen || - pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) { - client->errorValue = drawId; - return BadMatch; - } - - pReadDraw = (DrawablePtr)pGlxReadPbuffer; - new_reply.readVid = pGlxReadPbuffer->pFBConfig->id; - new_reply.readType = GLX_PBUFFER_TYPE; - } - } - - if (!pReadDraw) { - /* - ** Drawable is neither a Window nor a GLXPixmap. - */ - client->errorValue = readId; - return __glXBadDrawable; - } - - } else { - pReadDraw = pDraw; - pReadGlxPixmap = pGlxPixmap; - pReadWin = pWin; - new_reply.readVid = new_reply.writeVid; - new_reply.readType = new_reply.writeType; - } - - if (prevglxc) { - - if (prevglxc->pGlxPixmap) { - /* - ** The previous drawable was a glx pixmap, release it. - */ - prevglxc->pGlxPixmap->refcnt--; - __glXFreeGLXPixmap( prevglxc->pGlxPixmap ); - prevglxc->pGlxPixmap = 0; - } - - if (prevglxc->pGlxReadPixmap) { - /* - ** The previous drawable was a glx pixmap, release it. - */ - prevglxc->pGlxReadPixmap->refcnt--; - __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap ); - prevglxc->pGlxReadPixmap = 0; - } - - if (prevglxc->pGlxWindow) { - /* - ** The previous drawable was a glx window, release it. - */ - prevglxc->pGlxWindow->refcnt--; - __glXFreeGLXWindow( prevglxc->pGlxWindow ); - prevglxc->pGlxWindow = 0; - } - - if (prevglxc->pGlxReadWindow) { - /* - ** The previous drawable was a glx window, release it. - */ - prevglxc->pGlxReadWindow->refcnt--; - __glXFreeGLXWindow( prevglxc->pGlxReadWindow ); - prevglxc->pGlxReadWindow = 0; - } - - if (prevglxc->pGlxPbuffer) { - /* - ** The previous drawable was a glx Pbuffer, release it. - */ - prevglxc->pGlxPbuffer->refcnt--; - __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer ); - prevglxc->pGlxPbuffer = 0; - } - - if (prevglxc->pGlxReadPbuffer) { - /* - ** The previous drawable was a glx Pbuffer, release it. - */ - prevglxc->pGlxReadPbuffer->refcnt--; - __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer ); - prevglxc->pGlxReadPbuffer = 0; - } - - ChangeCurrentContext(cl, glxc, tag); - ChangeCurrentContext(cl, glxc, tag); - StopUsingContext(prevglxc); - } else { - tag = AddCurrentContext(cl, glxc, pDraw); - } - if (glxc) { - - glxc->pGlxPixmap = pGlxPixmap; - glxc->pGlxReadPixmap = pReadGlxPixmap; - glxc->pGlxWindow = pGlxWindow; - glxc->pGlxReadWindow = pGlxReadWindow; - glxc->pGlxPbuffer = pGlxPbuffer; - glxc->pGlxReadPbuffer = pGlxReadPbuffer; - - if (pGlxPixmap) { - pGlxPixmap->refcnt++; - } - - if (pReadGlxPixmap) { - pReadGlxPixmap->refcnt++; - } - - if (pGlxWindow) { - pGlxWindow->refcnt++; - } - - if (pGlxReadWindow) { - pGlxReadWindow->refcnt++; - } - - if (pGlxPbuffer) { - pGlxPbuffer->refcnt++; - } - - if (pGlxReadPbuffer) { - pGlxReadPbuffer->refcnt++; - } - - StartUsingContext(cl, glxc); - new_reply.contextTag = tag; - } else { - new_reply.contextTag = 0; - } - new_reply.length = 0; - new_reply.type = X_Reply; - new_reply.sequenceNumber = client->sequence; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - - if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) { - dixLookupResourceByClass((pointer*) &pXinDraw, - pDraw->id, XRC_DRAWABLE, - client, DixReadAccess); - } - - if (pReadDraw && pReadDraw != pDraw && - new_reply.readType != GLX_PBUFFER_TYPE) { - dixLookupResourceByClass((pointer*) &pXinReadDraw, - pReadDraw->id, XRC_DRAWABLE, - client, DixReadAccess); - } - else { - pXinReadDraw = pXinDraw; - } - } -#endif - - - /* send the MakeCurrent request to all required - * back-end servers. - */ - for (s = from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - unsigned int be_draw = None; - unsigned int be_read_draw = None; - - if (pGlxPixmap) { - be_draw = pGlxPixmap->be_xids[s]; - } - else if (pGlxPbuffer) { - be_draw = pGlxPbuffer->be_xids[s]; - } -#ifdef PANORAMIX - else if (pXinDraw) { - dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); - } -#endif - else if (pGlxWindow) { - pWin = (WindowPtr)pGlxWindow->pDraw; - } - - if (pWin && be_draw == None) { - be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - if (!be_draw) { - /* it might be that the window did not created yet on the */ - /* back-end server (lazy window creation option), force */ - /* creation of the window */ - dmxCreateAndRealizeWindow( pWin, TRUE ); - be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - } - } - - /* - * Before sending the MakeCurrent request - sync the - * X11 connection to the back-end servers to make sure - * that drawable is already created - */ - dmxSync( dmxScreen, 1 ); - - if (drawId == readId) { - LockDisplay(dpy); - GetReq(GLXMakeCurrent, be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXMakeCurrent; - be_req->drawable = be_draw; - be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); - be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); - if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) { - - /* The make current failed */ - UnlockDisplay(dpy); - SyncHandle(); - return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); - } - - UnlockDisplay(dpy); - SyncHandle(); - - SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag ); - } - else { - - if (pReadGlxPixmap) { - be_read_draw = pReadGlxPixmap->be_xids[s]; - } - else if (pGlxReadPbuffer) { - be_read_draw = pGlxReadPbuffer->be_xids[s]; - } -#ifdef PANORAMIX - else if (pXinReadDraw) { - dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client, - DixReadAccess); - } -#endif - else if (pGlxReadWindow) { - pReadWin = (WindowPtr)pGlxReadWindow->pDraw; - } - - if (pReadWin && be_read_draw == None) { - be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; - if (!be_read_draw) { - /* it might be that the window did not created yet on the */ - /* back-end server (lazy window creation option), force */ - /* creation of the window */ - dmxCreateAndRealizeWindow( pReadWin, TRUE ); - be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; - dmxSync( dmxScreen, 1 ); - } - } - - if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { - LockDisplay(dpy); - GetReq(GLXMakeContextCurrent, be_new_req); - be_new_req->reqType = dmxScreen->glxMajorOpcode; - be_new_req->glxCode = X_GLXMakeContextCurrent; - be_new_req->drawable = be_draw; - be_new_req->readdrawable = be_read_draw; - be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); - be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); - if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) { - - /* The make current failed */ - UnlockDisplay(dpy); - SyncHandle(); - return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); - } - - UnlockDisplay(dpy); - SyncHandle(); - - SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag ); - } - else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) { - xGLXMakeCurrentReadSGIReq *ext_req; - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXMakeCurrentReadSGIReply ext_reply; - - LockDisplay(dpy); - GetReqExtra(GLXVendorPrivateWithReply, - sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq, - vpreq); - ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq; - ext_req->reqType = dmxScreen->glxMajorOpcode; - ext_req->glxCode = X_GLXVendorPrivateWithReply; - ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI; - ext_req->drawable = be_draw; - ext_req->readable = be_read_draw; - ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); - ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); - if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) { - - /* The make current failed */ - UnlockDisplay(dpy); - SyncHandle(); - return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); - } - - UnlockDisplay(dpy); - SyncHandle(); - - SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag ); - - } - else { - return BadMatch; - } - } - - XFlush( dpy ); - } - - if (client->swapped) { - __glXSwapMakeCurrentReply(client, &new_reply); - } else { - WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply); - } - - return Success; -} - -int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc) -{ - xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; - - return( MakeCurrent(cl, req->drawable, req->drawable, - req->context, req->oldContextTag ) ); -} - -int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) -{ - xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; - - return( MakeCurrent(cl, req->drawable, req->readdrawable, - req->context, req->oldContextTag ) ); -} - -int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) -{ - xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; - - return( MakeCurrent(cl, req->drawable, req->readable, - req->context, req->oldContextTag ) ); -} - -int __glXIsDirect(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; - xGLXIsDirectReply reply; - __GLXcontext *glxc; - - /* - ** Find the GL context. - */ - dixLookupResourceByType((pointer*) &glxc, req->context, __glXContextRes, - NullClient, DixUnknownAccess); - if (!glxc) { - client->errorValue = req->context; - return __glXBadContext; - } - - reply.isDirect = 0; - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __glXSwapIsDirectReply(client, &reply); - } else { - WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); - } - - return Success; -} - -int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; -/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */ - xGLXQueryVersionReply reply; - - /* - ** Server should take into consideration the version numbers sent by the - ** client if it wants to work with older clients; however, in this - ** implementation the server just returns its version number. - */ - reply.majorVersion = __glXVersionMajor; - reply.minorVersion = __glXVersionMinor; - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __glXSwapQueryVersionReply(client, &reply); - } else { - WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); - } - return Success; -} - -int __glXWaitGL(__GLXclientState *cl, GLbyte *pc) -{ - xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; - xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc; - int from_screen = 0; - int to_screen = 0; - int s; - __GLXcontext *glxc = NULL; - - if (req->contextTag != 0) { - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (glxc) { - from_screen = to_screen = glxc->pScreen->myNum; - } - } - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReq(GLXWaitGL,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXWaitGL; - be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); - UnlockDisplay(dpy); - SyncHandle(); - - XSync(dpy, False); - } - - return Success; -} - -int __glXWaitX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXWaitXReq *req = (xGLXWaitXReq *)pc; - xGLXWaitXReq *be_req; - int from_screen = 0; - int to_screen = 0; - int s; - __GLXcontext *glxc = NULL; - - if (req->contextTag != 0) { - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (glxc) { - from_screen = to_screen = glxc->pScreen->myNum; - } - } - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - dmxSync( dmxScreen, 1 ); - - LockDisplay(dpy); - GetReq(GLXWaitX,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXWaitX; - be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); - UnlockDisplay(dpy); - SyncHandle(); - - XFlush( dpy ); - } - - return Success; -} - -int __glXCopyContext(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXCopyContextReq *be_req; - xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; - GLXContextID source = req->source; - GLXContextID dest = req->dest; - GLXContextTag tag = req->contextTag; - unsigned long mask = req->mask; - __GLXcontext *src, *dst; - int s; - int from_screen = 0; - int to_screen = 0; - - /* - ** Check that each context exists. - */ - dixLookupResourceByType((pointer*) &src, source, __glXContextRes, - NullClient, DixUnknownAccess); - if (!src) { - client->errorValue = source; - return __glXBadContext; - } - dixLookupResourceByType((pointer*) &dst, dest, __glXContextRes, - NullClient, DixUnknownAccess); - if (!dst) { - client->errorValue = dest; - return __glXBadContext; - } - - /* - ** They must be in the same address space, and same screen. - */ - if (src->pGlxScreen != dst->pGlxScreen) { - client->errorValue = source; - return BadMatch; - } - - /* - ** The destination context must not be current for any client. - */ - if (dst->isCurrent) { - client->errorValue = dest; - return BadAccess; - } - - if (tag) { - __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); - - if (!tagcx) { - return __glXBadContextTag; - } - if (tagcx != src) { - /* - ** This would be caused by a faulty implementation of the client - ** library. - */ - return BadMatch; - } - } - - from_screen = to_screen = src->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReq(GLXCopyContext,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXCopyContext; - be_req->source = (unsigned int)src->real_ids[s-from_screen]; - be_req->dest = (unsigned int)dst->real_ids[s-from_screen]; - be_req->mask = mask; - be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); - UnlockDisplay(dpy); - SyncHandle(); - } - - return Success; -} - -int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; - xGLXGetVisualConfigsReply reply; - __GLXscreenInfo *pGlxScreen; - __GLXvisualConfig *pGlxVisual; - CARD32 buf[__GLX_TOTAL_CONFIG]; - unsigned int screen; - int i, p; - - screen = req->screen; - if (screen >= screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - pGlxScreen = &__glXActiveScreens[screen]; - - reply.numVisuals = pGlxScreen->numGLXVisuals; - reply.numProps = __GLX_TOTAL_CONFIG; - reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 * - __GLX_TOTAL_CONFIG) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); - - for (i=0; i < pGlxScreen->numVisuals; i++) { - pGlxVisual = &pGlxScreen->pGlxVisual[i]; - if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) { - /* not a usable visual */ - continue; - } - p = 0; - buf[p++] = pGlxVisual->vid; - buf[p++] = pGlxVisual->class; - buf[p++] = pGlxVisual->rgba; - - buf[p++] = pGlxVisual->redSize; - buf[p++] = pGlxVisual->greenSize; - buf[p++] = pGlxVisual->blueSize; - buf[p++] = pGlxVisual->alphaSize; - buf[p++] = pGlxVisual->accumRedSize; - buf[p++] = pGlxVisual->accumGreenSize; - buf[p++] = pGlxVisual->accumBlueSize; - buf[p++] = pGlxVisual->accumAlphaSize; - - buf[p++] = pGlxVisual->doubleBuffer; - buf[p++] = pGlxVisual->stereo; - - buf[p++] = pGlxVisual->bufferSize; - buf[p++] = pGlxVisual->depthSize; - buf[p++] = pGlxVisual->stencilSize; - buf[p++] = pGlxVisual->auxBuffers; - buf[p++] = pGlxVisual->level; - /* - ** Add token/value pairs for extensions. - */ - buf[p++] = GLX_VISUAL_CAVEAT_EXT; - buf[p++] = pGlxVisual->visualRating; - buf[p++] = GLX_TRANSPARENT_TYPE_EXT; - buf[p++] = pGlxVisual->transparentPixel; - buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; - buf[p++] = pGlxVisual->transparentRed; - buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; - buf[p++] = pGlxVisual->transparentGreen; - buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; - buf[p++] = pGlxVisual->transparentBlue; - buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; - buf[p++] = pGlxVisual->transparentAlpha; - buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; - buf[p++] = pGlxVisual->transparentIndex; - buf[p++] = GLX_SAMPLES_SGIS; - buf[p++] = pGlxVisual->multiSampleSize; - buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; - buf[p++] = pGlxVisual->nMultiSampleBuffers; - buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; - buf[p++] = pGlxVisual->visualSelectGroup; - - WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, - (char *)buf); - } - return Success; -} - -/* -** Create a GLX Pixmap from an X Pixmap. -*/ -static int CreateGLXPixmap(__GLXclientState *cl, - VisualID visual, GLXFBConfigID fbconfigId, - int screenNum, XID pixmapId, XID glxpixmapId ) -{ - ClientPtr client = cl->client; - xGLXCreateGLXPixmapReq *be_req; - xGLXCreatePixmapReq *be_new_req; - DrawablePtr pDraw; - ScreenPtr pScreen; - VisualPtr pVisual; - __GLXpixmap *pGlxPixmap; - __GLXscreenInfo *pGlxScreen; - __GLXvisualConfig *pGlxVisual; - __GLXFBConfig *pFBConfig; - int i, s, rc; - int from_screen, to_screen; -#ifdef PANORAMIX - PanoramiXRes *pXinDraw = NULL; -#endif - - rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP, - DixAddAccess); - if (rc != Success) - return rc; - - /* - ** Check if screen of visual matches screen of pixmap. - */ - pScreen = pDraw->pScreen; - if (screenNum != pScreen->myNum) { - return BadMatch; - } - - if (fbconfigId == NULL && visual == NULL) { - return BadValue; - } - - if (fbconfigId != None) { - pFBConfig = glxLookupFBConfig( fbconfigId ); - if (!pFBConfig) { - client->errorValue = fbconfigId; - return BadValue; - } - visual = pFBConfig->associatedVisualId; - } - else { - pFBConfig = NULL; - } - - if (visual != None) { - /* - ** Find the VisualRec for this visual. - */ - pVisual = pScreen->visuals; - for (i=0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == visual) { - break; - } - } - if (i == pScreen->numVisuals) { - client->errorValue = visual; - return BadValue; - } - /* - ** Check if depth of visual matches depth of pixmap. - */ - if (pVisual->nplanes != pDraw->depth) { - client->errorValue = visual; - return BadMatch; - } - - /* - ** Get configuration of the visual. - */ - pGlxScreen = &__glXActiveScreens[screenNum]; - pGlxVisual = pGlxScreen->pGlxVisual; - for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { - if (pGlxVisual->vid == visual) { - break; - } - } - if (i == pGlxScreen->numVisuals) { - /* - ** Visual not support on this screen by this OpenGL implementation. - */ - client->errorValue = visual; - return BadValue; - } - - - /* find the FBConfig for that visual (if any) */ - if ( pFBConfig == NULL ) { - pFBConfig = glxLookupFBConfigByVID( visual ); - - if ( pFBConfig == NULL ) { - /* - * visual does not have an FBConfig ??? - client->errorValue = visual; - return BadValue; - */ - } - } - } - else { - pVisual = NULL; - pGlxVisual = NULL; - } - - pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap)); - if (!pGlxPixmap) { - return BadAlloc; - } - pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens); - if (!pGlxPixmap->be_xids) { - free( pGlxPixmap ); - return BadAlloc; - } - - pGlxPixmap->pDraw = pDraw; - pGlxPixmap->pGlxScreen = pGlxScreen; - pGlxPixmap->pGlxVisual = pGlxVisual; - pGlxPixmap->pFBConfig = pFBConfig; - pGlxPixmap->pScreen = pScreen; - pGlxPixmap->idExists = True; - pGlxPixmap->refcnt = 0; - - /* - ** Bump the ref count on the X pixmap so it won't disappear. - */ - ((PixmapPtr) pDraw)->refcnt++; - - /* - * send the request to the back-end server(s) - */ - from_screen = to_screen = screenNum; -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - - dixLookupResourceByClass((pointer*) &pXinDraw, - pDraw->id, XRC_DRAWABLE, - client, DixReadAccess); - } -#endif - - for (s=from_screen; s<=to_screen; s++) { - - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - Pixmap be_pixmap; - DrawablePtr pRealDraw = pDraw; - -#ifdef PANORAMIX - if (pXinDraw) { - dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0, - DixAddAccess); - } -#endif - - be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap; - - /* make sure pixmap already created on back-end */ - dmxSync( dmxScreen, 1 ); - - if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); - - LockDisplay(dpy); - pGlxPixmap->be_xids[s] = XAllocID(dpy); - GetReq(GLXCreatePixmap,be_new_req); - be_new_req->reqType = dmxScreen->glxMajorOpcode; - be_new_req->glxCode = X_GLXCreatePixmap; - be_new_req->screen = DefaultScreen(dpy); - be_new_req->fbconfig = be_FBConfig->id; - be_new_req->pixmap = (unsigned int)be_pixmap; - be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; - be_new_req->numAttribs = 0; - UnlockDisplay(dpy); - SyncHandle(); - } - else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) { - __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); - xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req; - xGLXVendorPrivateReq *vpreq; - - LockDisplay(dpy); - pGlxPixmap->be_xids[s] = XAllocID(dpy); - GetReqExtra(GLXVendorPrivate, - sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq, - vpreq); - ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq; - ext_req->reqType = dmxScreen->glxMajorOpcode; - ext_req->glxCode = X_GLXVendorPrivate; - ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; - ext_req->screen = DefaultScreen(dpy); - ext_req->fbconfig = be_FBConfig->id; - ext_req->pixmap = (unsigned int)be_pixmap; - ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; - UnlockDisplay(dpy); - SyncHandle(); - } - else if (pGlxVisual) { - LockDisplay(dpy); - pGlxPixmap->be_xids[s] = XAllocID(dpy); - GetReq(GLXCreateGLXPixmap,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXCreateGLXPixmap; - be_req->screen = DefaultScreen(dpy); - be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList( - pGlxVisual, - dmxScreen->glxVisuals, - dmxScreen->numGlxVisuals ); - be_req->pixmap = (unsigned int)be_pixmap; - be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; - UnlockDisplay(dpy); - SyncHandle(); - } - else { - client->errorValue = ( visual ? visual : fbconfigId ); - free( pGlxPixmap ); - return BadValue; - } - - XFlush( dpy ); - } - - if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) { - free( pGlxPixmap ); - return BadAlloc; - } - - return Success; -} - -int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; - - return( CreateGLXPixmap(cl, req->visual, None, - req->screen, req->pixmap, req->glxpixmap) ); -} - -int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; - - return( CreateGLXPixmap(cl, None, req->fbconfig, - req->screen, req->pixmap, req->glxpixmap) ); -} - -int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; - XID glxpixmap = req->glxpixmap; - __GLXpixmap *pGlxPixmap; - int s; - int from_screen, to_screen; - - /* - ** Check if it's a valid GLX pixmap. - */ - dixLookupResourceByType((pointer*) &pGlxPixmap, glxpixmap, - __glXPixmapRes, NullClient, DixUnknownAccess); - if (!pGlxPixmap) { - client->errorValue = glxpixmap; - return __glXBadPixmap; - } - FreeResource(glxpixmap, FALSE); - - /* - * destroy the pixmap on the back-end server(s). - */ - from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum; -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - /* make sure pixmap exist in back-end */ - dmxSync( dmxScreen, 1 ); - - LockDisplay(dpy); - GetReq(GLXDestroyGLXPixmap,req); - req->reqType = dmxScreen->glxMajorOpcode; - req->glxCode = X_GLXDestroyGLXPixmap; - req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; - UnlockDisplay(dpy); - SyncHandle(); - } - - - return Success; -} - -/*****************************************************************************/ - -/* -** NOTE: There is no portable implementation for swap buffers as of -** this time that is of value. Consequently, this code must be -** implemented by somebody other than SGI. -*/ -int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag) -{ - ClientPtr client = cl->client; - DrawablePtr pDraw; - xGLXSwapBuffersReq *be_req; - WindowPtr pWin = NULL; - __GLXpixmap *pGlxPixmap = NULL; - __GLXcontext *glxc = NULL; -#ifdef PANORAMIX - PanoramiXRes *pXinDraw = NULL; -#endif - __glXWindow *pGlxWindow = NULL; - int from_screen = 0; - int to_screen = 0; - int s, rc; - - /* - ** Check that the GLX drawable is valid. - */ - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); - if (rc == Success) { - from_screen = to_screen = pDraw->pScreen->myNum; - - if (pDraw->type == DRAWABLE_WINDOW) { - /* - ** Drawable is an X window. - */ - pWin = (WindowPtr)pDraw; - } else { - /* - ** Drawable is an X pixmap, which is not allowed. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - if (!pDraw) { - dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, - __glXPixmapRes, NullClient, DixUnknownAccess); - if (pGlxPixmap) { - /* - ** Drawable is a GLX pixmap. - */ - pDraw = pGlxPixmap->pDraw; - from_screen = to_screen = pGlxPixmap->pScreen->myNum; - } - } - - if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxWindow, drawId, - __glXWindowRes, NullClient, DixUnknownAccess); - if (pGlxWindow) { - /* - ** Drawable is a GLXWindow. - */ - pDraw = pGlxWindow->pDraw; - from_screen = to_screen = pGlxWindow->pScreen->myNum; - } - } - - if (!pDraw) { - /* - ** Drawable is neither a X window nor a GLX pixmap. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - - if (tag) { - glxc = __glXLookupContextByTag(cl, tag); - if (!glxc) { - return __glXBadContextTag; - } - } - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - dixLookupResourceByClass((pointer*) &pXinDraw, - pDraw->id, XRC_DRAWABLE, - client, DixReadAccess); - } -#endif - - /* If requested, send a glFinish to all back-end servers before swapping. */ - if (dmxGLXFinishSwap) { - for (s=from_screen; s<=to_screen; s++) { - Display *dpy = GetBackEndDisplay(cl,s); - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - xGLXSingleReq *finishReq; - xGLXSingleReply reply; - -#define X_GLXSingle 0 /* needed by GetReq below */ - - LockDisplay(dpy); - GetReq(GLXSingle,finishReq); - finishReq->reqType = dmxScreen->glxMajorOpcode; - finishReq->glxCode = X_GLsop_Finish; - finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0); - (void) _XReply(dpy, (xReply*) &reply, 0, False); - UnlockDisplay(dpy); - SyncHandle(); - } - } - - /* If requested, send an XSync to all back-end servers before swapping. */ - if (dmxGLXSyncSwap) { - for (s=from_screen; s<=to_screen; s++) - XSync(GetBackEndDisplay(cl,s), False); - } - - - /* send the SwapBuffers request to all back-end servers */ - - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - unsigned int be_draw = 0; - - if (pGlxPixmap) { - be_draw = (unsigned int)pGlxPixmap->be_xids[s]; - } -#ifdef PANORAMIX - else if (pXinDraw) { - dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); - } -#endif - else if (pGlxWindow) { - pWin = (WindowPtr)pGlxWindow->pDraw; - } - - if (pWin && !be_draw) { - be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - if (!be_draw) { - /* it might be that the window did not created yet on the */ - /* back-end server (lazy window creation option), force */ - /* creation of the window */ - dmxCreateAndRealizeWindow( pWin, TRUE ); - be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - } - } - - dmxSync( dmxScreen, 1 ); - - LockDisplay(dpy); - GetReq(GLXSwapBuffers,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXSwapBuffers; - be_req->drawable = be_draw; - be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 ); - UnlockDisplay(dpy); - SyncHandle(); - XFlush(dpy); - } - - return Success; -} - -int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - DrawablePtr pDraw; - xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; - GLXContextTag tag = req->contextTag; - XID drawId = req->drawable; - __GLXpixmap *pGlxPixmap = NULL; - __GLXcontext *glxc = NULL; - __glXWindow *pGlxWindow = NULL; - int rc; - - /* - ** Check that the GLX drawable is valid. - */ - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); - if (rc == Success) { - if (pDraw->type != DRAWABLE_WINDOW) { - /* - ** Drawable is an X pixmap, which is not allowed. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - if (!pDraw) { - dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, - __glXPixmapRes, NullClient, DixUnknownAccess); - if (pGlxPixmap) { - /* - ** Drawable is a GLX pixmap. - */ - pDraw = pGlxPixmap->pDraw; - } - } - - if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { - dixLookupResourceByType((pointer*) &pGlxWindow, drawId, - __glXWindowRes, NullClient, DixUnknownAccess); - if (pGlxWindow) { - /* - ** Drawable is a GLXWindow. - */ - pDraw = pGlxWindow->pDraw; - } - } - - if (!pDraw) { - /* - ** Drawable is neither a X window nor a GLX pixmap. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - - if (tag) { - glxc = __glXLookupContextByTag(cl, tag); - if (!glxc) { - return __glXBadContextTag; - } - } - - if (pDraw && - pDraw->type == DRAWABLE_WINDOW && - DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) { - return SGSwapBuffers(cl, drawId, tag, pDraw); - } - - return __glXDoSwapBuffers(cl, drawId, tag); -} - - -/************************************************************************/ - -/* -** Render and Renderlarge are not in the GLX API. They are used by the GLX -** client library to send batches of GL rendering commands. -*/ - -/* -** Execute all the drawing commands in a request. -*/ -int __glXRender(__GLXclientState *cl, GLbyte *pc) -{ - xGLXRenderReq *req; - xGLXRenderReq *be_req; - int size; - __GLXcontext *glxc; - int from_screen = 0; - int to_screen = 0; - int s; - - /* - ** NOTE: much of this code also appears in the byteswapping version of this - ** routine, __glXSwapRender(). Any changes made here should also be - ** duplicated there. - */ - - req = (xGLXRenderReq *) pc; - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return 0; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - pc += sz_xGLXRenderReq; - size = (req->length << 2) - sz_xGLXRenderReq; - - /* - * just forward the request to back-end server(s) - */ - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReq(GLXRender,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXRender; - be_req->length = req->length; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); - _XSend(dpy, (const char *)pc, size); - UnlockDisplay(dpy); - SyncHandle(); - } - - return Success; -} - -/* -** Execute a large rendering request (one that spans multiple X requests). -*/ -int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc) -{ - xGLXRenderLargeReq *req; - xGLXRenderLargeReq *be_req; - __GLXcontext *glxc; - int from_screen = 0; - int to_screen = 0; - int s; - - /* - ** NOTE: much of this code also appears in the byteswapping version of this - ** routine, __glXSwapRenderLarge(). Any changes made here should also be - ** duplicated there. - */ - - req = (xGLXRenderLargeReq *) pc; - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return 0; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - pc += sz_xGLXRenderLargeReq; - - /* - * just forward the request to back-end server(s) - */ - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - GetReq(GLXRenderLarge,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXRenderLarge; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); - be_req->length = req->length; - be_req->requestNumber = req->requestNumber; - be_req->requestTotal = req->requestTotal; - be_req->dataBytes = req->dataBytes; - Data(dpy, (const char *)pc, req->dataBytes); - UnlockDisplay(dpy); - SyncHandle(); - - } - - return Success; -} - - -/************************************************************************/ - -int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc) -{ - xGLXVendorPrivateReq *req; - - req = (xGLXVendorPrivateReq *) pc; - - switch( req->vendorCode ) { - - case X_GLvop_DeleteTexturesEXT: - return __glXVForwardSingleReq( cl, pc ); - break; - - case X_GLXvop_SwapIntervalSGI: - if (glxIsExtensionSupported("SGI_swap_control")) { - return __glXVForwardSingleReq( cl, pc ); - } - else { - return Success; - } - break; - -#if 0 /* glx 1.3 */ - case X_GLXvop_CreateGLXVideoSourceSGIX: - break; - case X_GLXvop_DestroyGLXVideoSourceSGIX: - break; - case X_GLXvop_CreateGLXPixmapWithConfigSGIX: - break; - case X_GLXvop_DestroyGLXPbufferSGIX: - break; - case X_GLXvop_ChangeDrawableAttributesSGIX: - break; -#endif - - case X_GLXvop_BindSwapBarrierSGIX: - return __glXBindSwapBarrierSGIX( cl, pc ); - break; - - case X_GLXvop_JoinSwapGroupSGIX: - return __glXJoinSwapGroupSGIX( cl, pc ); - break; - - case X_GLXvop_CreateContextWithConfigSGIX: - return __glXCreateContextWithConfigSGIX( cl, pc ); - break; - - default: - /* - ** unsupported private request - */ - cl->client->errorValue = req->vendorCode; - return __glXUnsupportedPrivateRequest; - } - - cl->client->errorValue = req->vendorCode; - return __glXUnsupportedPrivateRequest; - -} - -int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) -{ - xGLXVendorPrivateWithReplyReq *req; - - req = (xGLXVendorPrivateWithReplyReq *) pc; - - switch( req->vendorCode ) { - - case X_GLvop_GetConvolutionFilterEXT: - case X_GLvop_GetConvolutionParameterfvEXT: - case X_GLvop_GetConvolutionParameterivEXT: - case X_GLvop_GetSeparableFilterEXT: - case X_GLvop_GetHistogramEXT: - case X_GLvop_GetHistogramParameterivEXT: - case X_GLvop_GetMinmaxEXT: - case X_GLvop_GetMinmaxParameterfvEXT: - case X_GLvop_GetMinmaxParameterivEXT: - case X_GLvop_AreTexturesResidentEXT: - case X_GLvop_IsTextureEXT: - return( __glXVForwardPipe0WithReply(cl, pc) ); - break; - - case X_GLvop_GenTexturesEXT: - return( __glXVForwardAllWithReply(cl, pc) ); - break; - - -#if 0 /* glx1.3 */ - case X_GLvop_GetDetailTexFuncSGIS: - case X_GLvop_GetSharpenTexFuncSGIS: - case X_GLvop_GetColorTableSGI: - case X_GLvop_GetColorTableParameterfvSGI: - case X_GLvop_GetColorTableParameterivSGI: - case X_GLvop_GetTexFilterFuncSGIS: - case X_GLvop_GetInstrumentsSGIX: - case X_GLvop_InstrumentsBufferSGIX: - case X_GLvop_PollInstrumentsSGIX: - case X_GLvop_FlushRasterSGIX: - case X_GLXvop_CreateGLXPbufferSGIX: - case X_GLXvop_GetDrawableAttributesSGIX: - case X_GLXvop_QueryHyperpipeNetworkSGIX: - case X_GLXvop_QueryHyperpipeConfigSGIX: - case X_GLXvop_HyperpipeConfigSGIX: - case X_GLXvop_DestroyHyperpipeConfigSGIX: -#endif - case X_GLXvop_QueryMaxSwapBarriersSGIX: - return( __glXQueryMaxSwapBarriersSGIX(cl, pc) ); - break; - - case X_GLXvop_GetFBConfigsSGIX: - return( __glXGetFBConfigsSGIX(cl, pc) ); - break; - - case X_GLXvop_MakeCurrentReadSGI: - return( __glXMakeCurrentReadSGI(cl, pc) ); - break; - - case X_GLXvop_QueryContextInfoEXT: - return( __glXQueryContextInfoEXT(cl,pc) ); - break; - - default: - /* - ** unsupported private request - */ - cl->client->errorValue = req->vendorCode; - return __glXUnsupportedPrivateRequest; - } - -} - -int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; - xGLXQueryExtensionsStringReply reply; - GLint screen; - size_t length; - int len, numbytes; - char *be_buf; - -#ifdef FWD_QUERY_REQ - xGLXQueryExtensionsStringReq *be_req; - xGLXQueryExtensionsStringReply be_reply; - DMXScreenInfo *dmxScreen; - Display *dpy; - int slop; -#endif - - screen = req->screen; - - /* - ** Check if screen exists. - */ - if ((screen < 0) || (screen >= screenInfo.numScreens)) { - client->errorValue = screen; - return BadValue; - } - -#ifdef FWD_QUERY_REQ - dmxScreen = &dmxScreens[screen]; - - /* Send the glXQueryServerString request */ - dpy = GetBackEndDisplay(cl,screen); - LockDisplay(dpy); - GetReq(GLXQueryExtensionsString,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXQueryServerString; - be_req->screen = DefaultScreen(dpy); - _XReply(dpy, (xReply*) &be_reply, 0, False); - len = (int)be_reply.length; - numbytes = (int)be_reply.n; - slop = numbytes * __GLX_SIZE_INT8 & 3; - be_buf = (char *)malloc(numbytes); - if (!be_buf) { - /* Throw data on the floor */ - _XEatData(dpy, len); - } else { - _XRead(dpy, (char *)be_buf, numbytes); - if (slop) _XEatData(dpy,4-slop); - } - UnlockDisplay(dpy); - SyncHandle(); - -#else - - be_buf = __glXGetServerString(GLX_EXTENSIONS); - numbytes = strlen(be_buf) + 1; - len = __GLX_PAD(numbytes) >> 2; - -#endif - - length = len; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = len; - reply.n = numbytes; - - if (client->swapped) { - glxSwapQueryExtensionsStringReply(client, &reply, be_buf); - } else { - WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); - WriteToClient(client, (int)(length << 2), (char *)be_buf); - } - - return Success; -} - -int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; - xGLXQueryServerStringReply reply; - int name; - GLint screen; - size_t length; - int len, numbytes; - char *be_buf; -#ifdef FWD_QUERY_REQ - xGLXQueryServerStringReq *be_req; - xGLXQueryServerStringReply be_reply; - DMXScreenInfo *dmxScreen; - Display *dpy; - int slop; -#endif - - name = req->name; - screen = req->screen; - /* - ** Check if screen exists. - */ - if ((screen < 0) || (screen >= screenInfo.numScreens)) { - client->errorValue = screen; - return BadValue; - } - -#ifdef FWD_QUERY_REQ - dmxScreen = &dmxScreens[screen]; - - /* Send the glXQueryServerString request */ - dpy = GetBackEndDisplay(cl,screen); - LockDisplay(dpy); - GetReq(GLXQueryServerString,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXQueryServerString; - be_req->screen = DefaultScreen(dpy); - be_req->name = name; - _XReply(dpy, (xReply*) &be_reply, 0, False); - len = (int)be_reply.length; - numbytes = (int)be_reply.n; - slop = numbytes * __GLX_SIZE_INT8 & 3; - be_buf = (char *)malloc(numbytes); - if (!be_buf) { - /* Throw data on the floor */ - _XEatData(dpy, len); - } else { - _XRead(dpy, (char *)be_buf, numbytes); - if (slop) _XEatData(dpy,4-slop); - } - UnlockDisplay(dpy); - SyncHandle(); - -#else - be_buf = __glXGetServerString(name); - numbytes = strlen(be_buf) + 1; - len = __GLX_PAD(numbytes) >> 2; -#endif - - length = len; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = length; - reply.n = numbytes; - - if (client->swapped) { - glxSwapQueryServerStringReply(client, &reply, be_buf); - } else { - WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); - WriteToClient(client, (int)(length << 2), be_buf); - } - - return Success; -} - -int __glXClientInfo(__GLXclientState *cl, GLbyte *pc) -{ - xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; - xGLXClientInfoReq *be_req; - const char *buf; - int from_screen = 0; - int to_screen = 0; - int s; - - cl->GLClientmajorVersion = req->major; - cl->GLClientminorVersion = req->minor; - free(cl->GLClientextensions); - buf = (const char *)(req+1); - cl->GLClientextensions = strdup(buf); - - to_screen = screenInfo.numScreens - 1; - - for (s=from_screen; s<=to_screen; s++) - { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReq(GLXClientInfo,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXClientInfo; - be_req->major = req->major; - be_req->minor = req->minor; - be_req->length = req->length; - be_req->numbytes = req->numbytes; - Data(dpy, buf, req->numbytes); - - UnlockDisplay(dpy); - SyncHandle(); - } - - return Success; -} - -int __glXUseXFont(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXUseXFontReq *req; - xGLXUseXFontReq *be_req; - FontPtr pFont; - __GLXcontext *glxc = NULL; - int from_screen = 0; - int to_screen = 0; - int s; - dmxFontPrivPtr pFontPriv; - DMXScreenInfo *dmxScreen; - Display *dpy; - - req = (xGLXUseXFontReq *) pc; - - if (req->contextTag != 0) { - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (glxc) { - from_screen = to_screen = glxc->pScreen->myNum; - } - } - - /* - ** Font can actually be either the ID of a font or the ID of a GC - ** containing a font. - */ - dixLookupResourceByType((pointer*) &pFont, req->font, RT_FONT, - NullClient, DixUnknownAccess); - if (!pFont) { - GC *pGC; - dixLookupResourceByType((pointer*) &pGC, req->font, - RT_GC, NullClient, - DixUnknownAccess); - if (!pGC) { - client->errorValue = req->font; - return BadFont; - } - pFont = pGC->font; - } - - pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex); - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - - for (s=from_screen; s<=to_screen; s++) { - dmxScreen = &dmxScreens[s]; - dpy = GetBackEndDisplay(cl,s); - - dmxSync( dmxScreen, 1 ); - - LockDisplay(dpy); - GetReq(GLXUseXFont,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXUseXFont; - be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); - be_req->font = pFontPriv->font[s]->fid; - be_req->first = req->first; - be_req->count = req->count; - be_req->listBase = req->listBase; - UnlockDisplay(dpy); - SyncHandle(); - - XSync( dpy, False ); - } - - return Success; -} - -/* - * start GLX 1.3 here - */ - -int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; - xGLXGetFBConfigsReply reply; - __GLXFBConfig *pFBConfig; - CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS]; - int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS; - unsigned int screen = req->screen; - int numFBConfigs, i, p; - __GLXscreenInfo *pGlxScreen; - - if (screen >= screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - - pGlxScreen = &__glXActiveScreens[screen]; - numFBConfigs = __glXNumFBConfigs; - - reply.numFBConfigs = numFBConfigs; - reply.numAttribs = numAttribs; - reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.numFBConfigs); - __GLX_SWAP_INT(&reply.numAttribs); - } - WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); - - for (i=0; i < numFBConfigs; i++) { - int associatedVisualId = 0; - int drawableTypeIndex; - pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ]; - - p = 0; - /* core attributes */ - buf[p++] = GLX_FBCONFIG_ID; - buf[p++] = pFBConfig->id; - buf[p++] = GLX_BUFFER_SIZE; - buf[p++] = pFBConfig->indexBits; - buf[p++] = GLX_LEVEL; - buf[p++] = pFBConfig->level; - buf[p++] = GLX_DOUBLEBUFFER; - buf[p++] = pFBConfig->doubleBufferMode; - buf[p++] = GLX_STEREO; - buf[p++] = pFBConfig->stereoMode; - buf[p++] = GLX_AUX_BUFFERS; - buf[p++] = pFBConfig->maxAuxBuffers; - buf[p++] = GLX_RED_SIZE; - buf[p++] = pFBConfig->redBits; - buf[p++] = GLX_GREEN_SIZE; - buf[p++] = pFBConfig->greenBits; - buf[p++] = GLX_BLUE_SIZE; - buf[p++] = pFBConfig->blueBits; - buf[p++] = GLX_ALPHA_SIZE; - buf[p++] = pFBConfig->alphaBits; - buf[p++] = GLX_DEPTH_SIZE; - buf[p++] = pFBConfig->depthBits; - buf[p++] = GLX_STENCIL_SIZE; - buf[p++] = pFBConfig->stencilBits; - buf[p++] = GLX_ACCUM_RED_SIZE; - buf[p++] = pFBConfig->accumRedBits; - buf[p++] = GLX_ACCUM_GREEN_SIZE; - buf[p++] = pFBConfig->accumGreenBits; - buf[p++] = GLX_ACCUM_BLUE_SIZE; - buf[p++] = pFBConfig->accumBlueBits; - buf[p++] = GLX_ACCUM_ALPHA_SIZE; - buf[p++] = pFBConfig->accumAlphaBits; - buf[p++] = GLX_RENDER_TYPE; - buf[p++] = pFBConfig->renderType; - buf[p++] = GLX_DRAWABLE_TYPE; - drawableTypeIndex = p; - buf[p++] = pFBConfig->drawableType; - buf[p++] = GLX_X_VISUAL_TYPE; - buf[p++] = pFBConfig->visualType; - buf[p++] = GLX_CONFIG_CAVEAT; - buf[p++] = pFBConfig->visualCaveat; - buf[p++] = GLX_TRANSPARENT_TYPE; - buf[p++] = pFBConfig->transparentType; - buf[p++] = GLX_TRANSPARENT_RED_VALUE; - buf[p++] = pFBConfig->transparentRed; - buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; - buf[p++] = pFBConfig->transparentGreen; - buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; - buf[p++] = pFBConfig->transparentBlue; - buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; - buf[p++] = pFBConfig->transparentAlpha; - buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; - buf[p++] = pFBConfig->transparentIndex; - buf[p++] = GLX_MAX_PBUFFER_WIDTH; - buf[p++] = pFBConfig->maxPbufferWidth; - buf[p++] = GLX_MAX_PBUFFER_HEIGHT; - buf[p++] = pFBConfig->maxPbufferHeight; - buf[p++] = GLX_MAX_PBUFFER_PIXELS; - buf[p++] = pFBConfig->maxPbufferPixels; - - /* - * find the visual of the back-end server and match a visual - * on the proxy. - * do only once - if a visual is not yet associated. - */ - if (pFBConfig->associatedVisualId == (unsigned int)-1) { - DMXScreenInfo *dmxScreen = &dmxScreens[screen]; - __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ]; - __GLXvisualConfig *pGlxVisual = NULL; - int v; - int found = 0; - for (v=0; vnumGlxVisuals; v++) { - if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) { - pGlxVisual = &dmxScreen->glxVisuals[v]; - break; - } - } - - if (pGlxVisual) { - for (v=0; vnumVisuals; v++) { - if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) { - associatedVisualId = pGlxScreen->pGlxVisual[v].vid; - found = 1; - break; - } - } - } - - if (!found) { - associatedVisualId = 0; - pFBConfig->drawableType &= ~(GLX_WINDOW_BIT); - buf[drawableTypeIndex] = pFBConfig->drawableType; - } -#ifdef PANORAMIX - else if (!noPanoramiXExtension) { - /* convert the associated visualId to the panoramix one */ - pFBConfig->associatedVisualId = - PanoramiXTranslateVisualID(screen, v); - } -#endif - } - else { - associatedVisualId = pFBConfig->associatedVisualId; - } - - buf[p++] = GLX_VISUAL_ID; - buf[p++] = associatedVisualId; - - /* SGIS_multisample attributes */ - buf[p++] = GLX_SAMPLES_SGIS; - buf[p++] = pFBConfig->multiSampleSize; - buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; - buf[p++] = pFBConfig->nMultiSampleBuffers; - - /* SGIX_pbuffer specific attributes */ - buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX; - buf[p++] = pFBConfig->optimalPbufferWidth; - buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX; - buf[p++] = pFBConfig->optimalPbufferHeight; - - buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; - buf[p++] = pFBConfig->visualSelectGroup; - - if (client->swapped) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs); - } - WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf); - } - return Success; -} - -int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc; - xGLXGetFBConfigsReq new_req; - - new_req.reqType = req->reqType; - new_req.glxCode = req->glxCode; - new_req.length = req->length; - new_req.screen = req->screen; - - return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) ); -} - - -int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; - int screen = req->screen; - GLXFBConfigID fbconfigId = req->fbconfig; - XID windowId = req->window; - XID glxwindowId = req->glxwindow; - DrawablePtr pDraw; - ScreenPtr pScreen; - __glXWindow *pGlxWindow; - __GLXFBConfig *pGlxFBConfig = NULL; - VisualPtr pVisual; - VisualID visId; - int i, rc; - pointer val; - - /* - ** Check if windowId is valid - */ - rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW, - DixAddAccess); - if (rc != Success) - return rc; - - /* - ** Check if screen of window matches screen of fbconfig. - */ - pScreen = pDraw->pScreen; - if (screen != pScreen->myNum) { - return BadMatch; - } - - /* - ** Find the FBConfigRec for this fbconfigid. - */ - if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { - client->errorValue = fbconfigId; - return __glXBadFBConfig; - } - visId = pGlxFBConfig->associatedVisualId; - - /* - ** Check if the fbconfig supports rendering to windows - */ - if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) { - return BadMatch; - } - - if (visId != None) { - /* - ** Check if the visual ID is valid for this screen. - */ - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == visId) { - break; - } - } - if (i == pScreen->numVisuals) { - client->errorValue = visId; - return BadValue; - } - - /* - ** Check if color buffer depth of fbconfig matches depth - ** of window. - */ - if (pVisual->nplanes != pDraw->depth) { - return BadMatch; - } - } else - /* - ** The window was created with no visual that corresponds - ** to fbconfig - */ - return BadMatch; - - /* - ** Check if there is already a fbconfig associated with this window - */ - if (Success == dixLookupResourceByType(&val, - glxwindowId, __glXWindowRes, - NullClient, DixUnknownAccess)) { - client->errorValue = glxwindowId; - return BadAlloc; - } - - pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow)); - if (!pGlxWindow) { - return BadAlloc; - } - - /* - ** Register this GLX window as a resource - */ - if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) { - return BadAlloc; - } - - pGlxWindow->pDraw = pDraw; - pGlxWindow->type = GLX_GLXWINDOW_TYPE; - pGlxWindow->idExists = True; - pGlxWindow->refcnt = 0; - pGlxWindow->pGlxFBConfig = pGlxFBConfig; - pGlxWindow->pScreen = pScreen; - - return Success; -} - -int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; - XID glxwindow = req->glxwindow; - pointer val; - - /* - ** Check if it's a valid GLX window. - */ - if (Success != dixLookupResourceByType(&val, - glxwindow, __glXWindowRes, - NullClient, DixUnknownAccess)) { - client->errorValue = glxwindow; - return __glXBadDrawable; - } - /* - ** The glx window destructor will check whether it's current before - ** freeing anything. - */ - FreeResource(glxwindow, RT_NONE); - - return Success; -} - -int __glXQueryContext(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - __GLXcontext *ctx; - xGLXQueryContextReq *req; - xGLXQueryContextReply reply; - int nProps; - int *sendBuf, *pSendBuf; - int nReplyBytes; - - req = (xGLXQueryContextReq *)pc; - dixLookupResourceByType((pointer*) &ctx, req->context, __glXContextRes, - NullClient, DixUnknownAccess); - if (!ctx) { - client->errorValue = req->context; - return __glXBadContext; - } - - nProps = 3; - - reply.length = nProps << 1; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.n = nProps; - - nReplyBytes = reply.length << 2; - sendBuf = (int *)malloc(nReplyBytes); - pSendBuf = sendBuf; - *pSendBuf++ = GLX_FBCONFIG_ID; - *pSendBuf++ = (int)(ctx->pFBConfig->id); - *pSendBuf++ = GLX_RENDER_TYPE; - *pSendBuf++ = (int)(ctx->pFBConfig->renderType); - *pSendBuf++ = GLX_SCREEN; - *pSendBuf++ = (int)(ctx->pScreen->myNum); - - if (client->swapped) { - __glXSwapQueryContextReply(client, &reply, sendBuf); - } else { - WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply); - WriteToClient(client, nReplyBytes, (char *)sendBuf); - } - free((char *)sendBuf); - - return Success; -} - -int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - __GLXcontext *ctx; - xGLXQueryContextInfoEXTReq *req; - xGLXQueryContextInfoEXTReply reply; - int nProps; - int *sendBuf, *pSendBuf; - int nReplyBytes; - - req = (xGLXQueryContextInfoEXTReq *)pc; - dixLookupResourceByType((pointer*) &ctx, - req->context, __glXContextRes, - client, DixReadAccess); - - if (!ctx) { - client->errorValue = req->context; - return __glXBadContext; - } - - nProps = 4; - - reply.length = nProps << 1; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.n = nProps; - - nReplyBytes = reply.length << 2; - sendBuf = (int *)malloc(nReplyBytes); - pSendBuf = sendBuf; - *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; - *pSendBuf++ = (int)(ctx->share_id); - *pSendBuf++ = GLX_VISUAL_ID_EXT; - *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0); - *pSendBuf++ = GLX_SCREEN_EXT; - *pSendBuf++ = (int)(ctx->pScreen->myNum); - *pSendBuf++ = GLX_FBCONFIG_ID; - *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0); - - if (client->swapped) { - __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); - } else { - WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); - WriteToClient(client, nReplyBytes, (char *)sendBuf); - } - free((char *)sendBuf); - - return Success; -} - -int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc; - xGLXCreatePbufferReq *be_req; - int screen = req->screen; - GLXFBConfigID fbconfigId = req->fbconfig; - GLXPbuffer pbuffer = req->pbuffer; - __glXPbuffer *pGlxPbuffer; - int numAttribs = req->numAttribs; - int *attr; - ScreenPtr pScreen; - __GLXFBConfig *pGlxFBConfig; - __GLXFBConfig *be_pGlxFBConfig; - XID be_xid; - Display *dpy; - DMXScreenInfo *dmxScreen; - int s; - int from_screen, to_screen; - - /* - ** Look up screen and FBConfig. - */ - if (screen >= screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - pScreen = screenInfo.screens[screen]; - - /* - ** Find the FBConfigRec for this fbconfigid. - */ - if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { - client->errorValue = fbconfigId; - return __glXBadFBConfig; - } - - /* - ** Create the GLX part of the Pbuffer. - */ - pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer)); - if (!pGlxPbuffer) { - return BadAlloc; - } - - pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens ); - if (!pGlxPbuffer->be_xids) { - free(pGlxPbuffer); - return BadAlloc; - } - - /* - * Allocate an XID on the back-end server(s) and send him the request - */ - from_screen = to_screen = screen; -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - for (s=from_screen; s<=to_screen; s++) { - dpy = GetBackEndDisplay(cl,s); - be_xid = XAllocID(dpy); - dmxScreen = &dmxScreens[s]; - be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s ); - - attr = (int *)( req+1 ); - - LockDisplay(dpy); - GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXCreatePbuffer; - be_req->screen = be_pGlxFBConfig->screen; - be_req->fbconfig = be_pGlxFBConfig->id; - be_req->pbuffer = be_xid; - be_req->numAttribs = numAttribs; - - /* Send attributes */ - if ( attr != NULL ) { - CARD32 *pc = (CARD32 *)(be_req + 1); - - while (numAttribs-- > 0) { - *pc++ = *attr++; /* token */ - *pc++ = *attr++; /* value */ - } - } - - UnlockDisplay(dpy); - SyncHandle(); - - pGlxPbuffer->be_xids[s] = be_xid; - } - - - pGlxPbuffer->idExists = True; - pGlxPbuffer->refcnt = 0; - pGlxPbuffer->pFBConfig = pGlxFBConfig; - pGlxPbuffer->pScreen = pScreen; - - /* - ** Register the resource. - */ - if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) { - return BadAlloc; - } - - return Success; - -} - -int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; - xGLXDestroyPbufferReq *be_req; - GLXPbuffer pbuffer = req->pbuffer; - Display *dpy; - int screen; - DMXScreenInfo *dmxScreen; - __glXPbuffer *pGlxPbuffer; - int s; - int from_screen, to_screen; - - /* - ** Check if it's a valid Pbuffer - */ - dixLookupResourceByType((pointer*) &pGlxPbuffer, pbuffer, - __glXPbufferRes, NullClient, DixUnknownAccess); - if (!pGlxPbuffer) { - client->errorValue = pbuffer; - return __glXBadPbuffer; - } - - screen = pGlxPbuffer->pScreen->myNum; - - from_screen = to_screen = screen; -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - for (s=from_screen; s<=to_screen; s++) { - dpy = GetBackEndDisplay(cl,s); - dmxScreen = &dmxScreens[s]; - - /* send the destroy request to the back-end server */ - LockDisplay(dpy); - GetReq(GLXDestroyPbuffer, be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXDestroyPbuffer; - be_req->pbuffer = pGlxPbuffer->be_xids[s]; - UnlockDisplay(dpy); - SyncHandle(); - } - - FreeResource(pbuffer, RT_NONE); - - return Success; -} - -int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; - xGLXGetDrawableAttributesReq *be_req; - xGLXGetDrawableAttributesReply reply; - ClientPtr client = cl->client; - GLXDrawable drawId = req->drawable; - GLXDrawable be_drawable = 0; - DrawablePtr pDraw = NULL; - Display *dpy; - int screen, rc; - DMXScreenInfo *dmxScreen; - CARD32 *attribs = NULL; - int attribs_size; -#ifdef PANORAMIX - PanoramiXRes *pXinDraw = NULL; -#endif - - if (drawId != None) { - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); - if (rc == Success) { - if (pDraw->type == DRAWABLE_WINDOW) { - WindowPtr pWin = (WindowPtr)pDraw; - be_drawable = 0; - screen = pWin->drawable.pScreen->myNum; - - } - else { - /* - ** Drawable is not a Window , GLXWindow or a GLXPixmap. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - if (!pDraw) { - __GLXpixmap *pGlxPixmap; - dixLookupResourceByType((pointer*) &pGlxPixmap, - drawId, __glXPixmapRes, - NullClient, DixUnknownAccess); - if (pGlxPixmap) { - pDraw = pGlxPixmap->pDraw; - screen = pGlxPixmap->pScreen->myNum; - be_drawable = pGlxPixmap->be_xids[screen]; - } - } - - if (!pDraw) { - __glXWindow *pGlxWindow; - dixLookupResourceByType((pointer*) &pGlxWindow, - drawId, __glXWindowRes, - NullClient, DixUnknownAccess); - if (pGlxWindow) { - pDraw = pGlxWindow->pDraw; - screen = pGlxWindow->pScreen->myNum; - be_drawable = 0; - } - } - - if (!pDraw) { - __glXPbuffer *pGlxPbuffer; - dixLookupResourceByType((pointer*) &pGlxPbuffer, - drawId, __glXPbufferRes, - NullClient, DixUnknownAccess); - if (pGlxPbuffer) { - pDraw = (DrawablePtr)pGlxPbuffer; - screen = pGlxPbuffer->pScreen->myNum; - be_drawable = pGlxPbuffer->be_xids[screen]; - } - } - - - if (!pDraw) { - /* - ** Drawable is not a Window , GLXWindow or a GLXPixmap. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - - /* if the drawable is a window or GLXWindow - - * we need to find the base id on the back-end server - */ - if (!be_drawable) { - WindowPtr pWin = (WindowPtr)pDraw; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, - pDraw->id, XRC_DRAWABLE, - client, DixReadAccess)) { - client->errorValue = drawId; - return __glXBadDrawable; - } - - dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, - DixReadAccess); - } -#endif - - if (pWin) { - be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - if (!be_drawable) { - /* it might be that the window did not created yet on the */ - /* back-end server (lazy window creation option), force */ - /* creation of the window */ - dmxCreateAndRealizeWindow( pWin, TRUE ); - be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - } - } - else { - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - - /* send the request to the back-end server */ - dpy = GetBackEndDisplay(cl,screen); - dmxScreen = &dmxScreens[screen]; - - /* make sure drawable exists on back-end */ - dmxSync( dmxScreen, 1 ); - - LockDisplay(dpy); - GetReq(GLXGetDrawableAttributes, be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXGetDrawableAttributes; - be_req->drawable = be_drawable; - be_req->length = req->length; - if (!_XReply(dpy, (xReply *) &reply, 0, False)) { - UnlockDisplay(dpy); - SyncHandle(); - return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); - } - - if (reply.numAttribs) { - attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32; - attribs = (CARD32 *) malloc(attribs_size); - if (attribs == NULL) { - UnlockDisplay(dpy); - SyncHandle(); - return BadAlloc; - } - - _XRead(dpy, (char *) attribs, attribs_size); - } - - UnlockDisplay(dpy); - SyncHandle(); - - - /* send the reply back to the client */ - reply.sequenceNumber = client->sequence; - if (client->swapped) { - __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs); - } - else { - WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply); - WriteToClient(client, attribs_size, (char *)attribs); - } - - free(attribs); - - return Success; -} - -int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ - xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc; - xGLXChangeDrawableAttributesReq *be_req; - ClientPtr client = cl->client; - GLXDrawable drawId = req->drawable; - GLXDrawable be_drawable = 0; - DrawablePtr pDraw = NULL; - Display *dpy; - int screen, rc; - DMXScreenInfo *dmxScreen; - - if (drawId != None) { - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess); - if (rc == Success) { - if (pDraw->type == DRAWABLE_WINDOW) { - WindowPtr pWin = (WindowPtr)pDraw; - be_drawable = 0; - screen = pWin->drawable.pScreen->myNum; - - } - else { - /* - ** Drawable is not a Window , GLXWindow or a GLXPixmap. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - if (!pDraw) { - __GLXpixmap *pGlxPixmap; - dixLookupResourceByType((pointer*) &pGlxPixmap, - drawId, __glXPixmapRes, - NullClient, DixUnknownAccess); - if (pGlxPixmap) { - pDraw = pGlxPixmap->pDraw; - screen = pGlxPixmap->pScreen->myNum; - be_drawable = pGlxPixmap->be_xids[screen]; - } - } - - if (!pDraw) { - __glXWindow *pGlxWindow; - dixLookupResourceByType((pointer*) &pGlxWindow, - drawId, __glXWindowRes, - NullClient, DixUnknownAccess); - if (pGlxWindow) { - pDraw = pGlxWindow->pDraw; - screen = pGlxWindow->pScreen->myNum; - be_drawable = 0; - } - } - - if (!pDraw) { - __glXPbuffer *pGlxPbuffer; - dixLookupResourceByType((pointer*) &pGlxPbuffer, - drawId, __glXPbufferRes, - NullClient, DixUnknownAccess); - if (pGlxPbuffer) { - pDraw = (DrawablePtr)pGlxPbuffer; - screen = pGlxPbuffer->pScreen->myNum; - be_drawable = pGlxPbuffer->be_xids[screen]; - } - } - - - if (!pDraw) { - /* - ** Drawable is not a Window , GLXWindow or a GLXPixmap. - */ - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - - /* if the drawable is a window or GLXWindow - - * we need to find the base id on the back-end server - */ - if (!be_drawable) { - WindowPtr pWin = (WindowPtr)pDraw; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - PanoramiXRes *pXinDraw; - if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, - pDraw->id, XRC_DRAWABLE, - client, DixReadAccess)) { - client->errorValue = drawId; - return __glXBadDrawable; - } - - dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, - DixReadAccess); - } -#endif - - if (pWin) { - be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - if (!be_drawable) { - /* it might be that the window did not created yet on the */ - /* back-end server (lazy window creation option), force */ - /* creation of the window */ - dmxCreateAndRealizeWindow( pWin, TRUE ); - be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; - } - } - else { - client->errorValue = drawId; - return __glXBadDrawable; - } - } - - - /* send the request to the back-end server */ - dpy = GetBackEndDisplay(cl,screen); - dmxScreen = &dmxScreens[screen]; - - /* make sure drawable exists on back-end */ - dmxSync( dmxScreen, 1 ); - - LockDisplay(dpy); - GetReqExtra(GLXChangeDrawableAttributes, - 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLXChangeDrawableAttributes; - be_req->drawable = be_drawable; - be_req->numAttribs = req->numAttribs; - be_req->length = req->length; - - UnlockDisplay(dpy); - SyncHandle(); - - return Success; -} - -int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag) -{ - ClientPtr client = cl->client; - xGLXRenderLargeReq *req; - GLint maxSize, amount; - GLint totalRequests, requestNumber; - GLint dataLen; - GLbyte *data; - __GLXcontext *glxc; - int s; - int from_screen, to_screen; - - maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq); - dataLen = cl->largeCmdBytesTotal; - totalRequests = (dataLen / maxSize); - if (dataLen % maxSize) totalRequests++; - - glxc = __glXLookupContextByTag(cl, contextTag); - if (!glxc) { - client->errorValue = contextTag; - return __glXBadContext; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - /* - ** Send enough requests until the whole array is sent. - */ - requestNumber = 1; - data = cl->largeCmdBuf; - while (dataLen > 0) { - amount = dataLen; - if (amount > maxSize) { - amount = maxSize; - } - - for (s=from_screen; s<=to_screen; s++) { - - Display *dpy = GetBackEndDisplay(cl,s); - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - - LockDisplay(dpy); - GetReq(GLXRenderLarge,req); - req->reqType = dmxScreen->glxMajorOpcode; - req->glxCode = X_GLXRenderLarge; - req->contextTag = GetCurrentBackEndTag(cl,contextTag,s); - req->length += (amount + 3) >> 2; - req->requestNumber = requestNumber++; - req->requestTotal = totalRequests; - req->dataBytes = amount; - Data(dpy, ((const char*)data), amount); - dataLen -= amount; - data = ((GLbyte *) data) + amount; - UnlockDisplay(dpy); - SyncHandle(); - } - } - - return Success; -} +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DMX_CONFIG_H +#include +#endif + +#include "dmx.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" +#include "dmxfont.h" +#include "dmxsync.h" + +#include "glxserver.h" +#include +#include "g_disptab.h" +#include +#include +#include "glxutil.h" +#include "glxext.h" +#include "unpack.h" + +#include "GL/glxproto.h" +#include "glxvendor.h" +#include "glxvisuals.h" +#include "glxswap.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +extern __GLXFBConfig **__glXFBConfigs; +extern int __glXNumFBConfigs; + +extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id ); +extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid ); +extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen ); +extern int glxIsExtensionSupported( char *ext ); +extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); + +#define BE_TO_CLIENT_ERROR(x) \ + ( (x) >= __glXerrorBase ? \ + (x) - dmxScreen->glxErrorBase + __glXerrorBase \ + : (x) ) + +Display *GetBackEndDisplay( __GLXclientState *cl, int s ) +{ + if (! cl->be_displays[s] ) { + cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) ); + } + return cl->be_displays[s]; +} + +/* +** Create a GL context with the given properties. +*/ +static int CreateContext(__GLXclientState *cl, + GLXContextID gcId, + VisualID vid, GLXFBConfigID fbconfigId, + int screen, + GLXContextID shareList, + int isDirect ) +{ + ClientPtr client = cl->client; + xGLXCreateContextReq *be_req; + xGLXCreateNewContextReq *be_new_req; + VisualPtr pVisual; + ScreenPtr pScreen; + __GLXcontext *glxc, *shareglxc; + __GLXvisualConfig *pGlxVisual; + __GLXscreenInfo *pGlxScreen; + VisualID visual = vid; + GLint i; + int from_screen = screen; + int to_screen = screen; + DMXScreenInfo *dmxScreen; + VisualID be_vid = 0; + GLXFBConfigID be_fbconfigId = 0; + int num_be_screens; + Display *dpy; + + /* + ** Check if screen exists. + */ + if (screen >= screenInfo.numScreens) { + client->errorValue = screen; + return BadValue; + } + + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + /* + ** Find the display list space that we want to share. + ** + */ + if (shareList == None) { + shareglxc = NULL; + } else { + dixLookupResourceByType((pointer*) &shareglxc, shareList, + __glXContextRes, NullClient, DixUnknownAccess); + if (!shareglxc) { + client->errorValue = shareList; + return __glXBadContext; + } + } + + /* + ** Allocate memory for the new context + */ + glxc = calloc(1, sizeof(__GLXcontext)); + if (!glxc) { + return BadAlloc; + } + + pScreen = screenInfo.screens[screen]; + pGlxScreen = &__glXActiveScreens[screen]; + + if (fbconfigId != None) { + glxc->pFBConfig = glxLookupFBConfig( fbconfigId ); + if (!glxc->pFBConfig) { + client->errorValue = fbconfigId; + free( glxc ); + return BadValue; + } + visual = glxc->pFBConfig->associatedVisualId; + } + else { + glxc->pFBConfig = NULL; + } + + if (visual != None) { + /* + ** Check if the visual ID is valid for this screen. + */ + pVisual = pScreen->visuals; + for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { + if (pVisual->vid == visual) { + break; + } + } + if (i == pScreen->numVisuals) { + client->errorValue = visual; + free( glxc ); + return BadValue; + } + + pGlxVisual = pGlxScreen->pGlxVisual; + for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { + if (pGlxVisual->vid == visual) { + break; + } + } + if (i == pGlxScreen->numVisuals) { + /* + ** Visual not support on this screen by this OpenGL implementation. + */ + client->errorValue = visual; + free( glxc ); + return BadValue; + } + + if ( glxc->pFBConfig == NULL ) { + glxc->pFBConfig = glxLookupFBConfigByVID( visual ); + + if ( glxc->pFBConfig == NULL ) { + /* + * visual does not have an FBConfig ??? + client->errorValue = visual; + free( glxc ); + return BadValue; + */ + } + } + } + else { + pVisual = NULL; + pGlxVisual = NULL; + } + + glxc->pScreen = pScreen; + glxc->pGlxScreen = pGlxScreen; + glxc->pVisual = pVisual; + glxc->pGlxVisual = pGlxVisual; + + /* + * allocate memory for back-end servers info + */ + num_be_screens = to_screen - from_screen + 1; + glxc->real_ids = (XID *)malloc(sizeof(XID) * num_be_screens); + if (!glxc->real_ids) { + return BadAlloc; + } + glxc->real_vids = (XID *)malloc(sizeof(XID) * num_be_screens); + if (!glxc->real_vids) { + return BadAlloc; + } + + for (screen = from_screen; screen <= to_screen; screen++) { + int sent = 0; + pScreen = screenInfo.screens[screen]; + pGlxScreen = &__glXActiveScreens[screen]; + dmxScreen = &dmxScreens[screen]; + + if (glxc->pFBConfig) { + __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id, + screen ); + be_fbconfigId = beFBConfig->id; + } + + if (pGlxVisual) { + + be_vid = glxMatchGLXVisualInConfigList( pGlxVisual, + dmxScreen->glxVisuals, + dmxScreen->numGlxVisuals ); + + if (!be_vid) { + /* visual is not supported on the back-end server */ + free( glxc->real_ids ); + free( glxc->real_vids ); + free( glxc ); + return BadValue; + } + } + + glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen)); + + /* send the create context request to the back-end server */ + dpy = GetBackEndDisplay(cl,screen); + if (glxc->pFBConfig) { + /*Since for a certain visual both RGB and COLOR INDEX + *can be on then the only parmeter to choose the renderType + * should be the class of the colormap since all 4 first + * classes does not support RGB mode only COLOR INDEX , + * and so TrueColor and DirectColor does not support COLOR INDEX*/ + int renderType = glxc->pFBConfig->renderType; + if ( pVisual ) { + switch ( pVisual->class ){ + case PseudoColor: + case StaticColor: + case GrayScale: + case StaticGray: + renderType = GLX_COLOR_INDEX_TYPE; + break; + case TrueColor: + case DirectColor: + default: + renderType = GLX_RGBA_TYPE; + break; + } + } + if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { + LockDisplay(dpy); + GetReq(GLXCreateNewContext,be_new_req); + be_new_req->reqType = dmxScreen->glxMajorOpcode; + be_new_req->glxCode = X_GLXCreateNewContext; + be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; + be_new_req->fbconfig = (unsigned int)be_fbconfigId; + be_new_req->screen = DefaultScreen(dpy); + be_new_req->renderType = renderType; + + be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); + be_new_req->isDirect = 0; + UnlockDisplay(dpy); + glxc->real_vids[screen-from_screen] = be_fbconfigId; + sent = 1; + } + else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) { + + xGLXCreateContextWithConfigSGIXReq *ext_req; + xGLXVendorPrivateReq *vpreq; + LockDisplay(dpy); + GetReqExtra(GLXVendorPrivate, + sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq, + vpreq); + ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq; + ext_req->reqType = dmxScreen->glxMajorOpcode; + ext_req->glxCode = X_GLXVendorPrivate; + ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; + ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; + ext_req->fbconfig = (unsigned int)be_fbconfigId; + ext_req->screen = DefaultScreen(dpy); + ext_req->renderType = renderType; + ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); + ext_req->isDirect = 0; + UnlockDisplay(dpy); + glxc->real_vids[screen-from_screen] = be_fbconfigId; + sent = 1; + } + } + + if (!sent) { + LockDisplay(dpy); + GetReq(GLXCreateContext,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCreateContext; + be_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; + be_req->visual = (unsigned int)be_vid; + be_req->screen = DefaultScreen(dpy); + be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); + be_req->isDirect = 0; + UnlockDisplay(dpy); + glxc->real_vids[screen-from_screen] = be_vid; + } + SyncHandle(); + + } + + /* + ** Register this context as a resource. + */ + if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { + free( glxc->real_ids ); + free( glxc->real_vids ); + free( glxc ); + client->errorValue = gcId; + return BadAlloc; + } + + /* + ** Finally, now that everything is working, setup the rest of the + ** context. + */ + glxc->id = gcId; + glxc->share_id = shareList; + glxc->idExists = GL_TRUE; + glxc->isCurrent = GL_FALSE; + + return Success; +} + +int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; + + return( CreateContext(cl, req->context,req->visual, None, + req->screen, req->shareList, req->isDirect) ); + +} + +int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; + + return( CreateContext(cl, req->context,None, req->fbconfig, + req->screen, req->shareList, req->isDirect) ); + +} + +int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; + + return( CreateContext(cl, req->context, None, req->fbconfig, + req->screen, req->shareList, req->isDirect) ); + +} + +int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryMaxSwapBarriersSGIXReq *req = + (xGLXQueryMaxSwapBarriersSGIXReq *)pc; + xGLXQueryMaxSwapBarriersSGIXReply reply; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = 0; + reply.max = QueryMaxSwapBarriersSGIX(req->screen); + + if (client->swapped) { + __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, + (char *)&reply); + } + + return Success; +} + +int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc; + DrawablePtr pDraw; + __GLXpixmap *pGlxPixmap = NULL; + __glXWindow *pGlxWindow = NULL; + int rc; + + rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess); + if (rc != Success) { + dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) pDraw = pGlxWindow->pDraw; + } + + if (!pDraw) { + client->errorValue = req->drawable; + return __glXBadDrawable; + } + + return BindSwapBarrierSGIX(pDraw, req->barrier); +} + +int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc; + DrawablePtr pDraw, pMember = NULL; + __GLXpixmap *pGlxPixmap = NULL; + __glXWindow *pGlxWindow = NULL; + int rc; + + rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess); + if (rc != Success) { + dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) pDraw = pGlxWindow->pDraw; + } + + if (!pDraw) { + client->errorValue = req->drawable; + return __glXBadDrawable; + } + + if (req->member != None) { + rc = dixLookupDrawable(&pMember, req->member, client, 0, + DixGetAttrAccess); + if (rc != Success) { + dixLookupResourceByType((pointer*) &pGlxPixmap, req->member, + __glXPixmapRes, NullClient, + DixUnknownAccess); + if (pGlxPixmap) pMember = pGlxPixmap->pDraw; + } + + if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, req->member, + __glXWindowRes, NullClient, + DixUnknownAccess); + if (pGlxWindow) pMember = pGlxWindow->pDraw; + } + + if (!pMember) { + client->errorValue = req->member; + return __glXBadDrawable; + } + } + + return JoinSwapGroupSGIX(pDraw, pMember); +} + + +/* +** Destroy a GL context as an X resource. +*/ +int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; + xGLXDestroyContextReq *be_req; + GLXContextID gcId = req->context; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int s; + + dixLookupResourceByType((pointer*) &glxc, gcId, __glXContextRes, + NullClient, DixUnknownAccess); + if (glxc) { + /* + ** Just free the resource; don't actually destroy the context, + ** because it might be in use. The + ** destroy method will be called by the resource destruction routine + ** if necessary. + */ + FreeResourceByType(gcId, __glXContextRes, FALSE); + + from_screen = to_screen = glxc->pScreen->myNum; + + } else { + client->errorValue = gcId; + return __glXBadContext; + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + /* + * send DestroyContext request to all back-end servers + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXDestroyContext,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXDestroyContext; + be_req->context = glxc->real_ids[s-from_screen]; + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +/*****************************************************************************/ + +/* +** For each client, the server keeps a table of all the contexts that are +** current for that client (each thread of a client may have its own current +** context). These routines add, change, and lookup contexts in the table. +*/ + +/* +** Add a current context, and return the tag that will be used to refer to it. +*/ +static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw) +{ + int i; + int num = cl->numCurrentContexts; + __GLXcontext **table = cl->currentContexts; + + if (!glxc) return -1; + + /* + ** Try to find an empty slot and use it. + */ + for (i=0; i < num; i++) { + if (!table[i]) { + table[i] = glxc; + return i+1; + } + } + /* + ** Didn't find a free slot, so we'll have to grow the table. + */ + if (!num) { + table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); + cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr)); + cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens *sizeof(GLXContextTag)); + } else { + table = (__GLXcontext **) realloc(table, + (num+1)*sizeof(__GLXcontext *)); + cl->currentDrawables = (DrawablePtr *) realloc( + cl->currentDrawables , + (num+1)*sizeof(DrawablePtr)); + cl->be_currentCTag = (GLXContextTag *) realloc(cl->be_currentCTag, + (num+1)*screenInfo.numScreens*sizeof(GLXContextTag)); + } + table[num] = glxc; + cl->currentDrawables[num] = pDraw; + cl->currentContexts = table; + cl->numCurrentContexts++; + + memset(cl->be_currentCTag + num*screenInfo.numScreens, 0, + screenInfo.numScreens * sizeof(GLXContextTag)); + + return num+1; +} + +/* +** Given a tag, change the current context for the corresponding entry. +*/ +static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, + GLXContextTag tag) +{ + __GLXcontext **table = cl->currentContexts; + table[tag-1] = glxc; +} + +/* +** Given a tag, and back-end screen number, retrives the current back-end +** tag. +*/ +int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s) +{ + if (tag >0) { + return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] ); + } + else { + return 0; + } +} + +/* +** Given a tag, and back-end screen number, sets the current back-end +** tag. +*/ +static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag) +{ + if (tag >0) { + cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag; + } +} + +/* +** For this implementation we have chosen to simply use the index of the +** context's entry in the table as the context tag. A tag must be greater +** than 0. +*/ +__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) +{ + int num = cl->numCurrentContexts; + + if (tag < 1 || tag > num) { + return 0; + } else { + return cl->currentContexts[tag-1]; + } +} + +DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag) +{ + int num = cl->numCurrentContexts; + + if (tag < 1 || tag > num) { + return 0; + } else { + return cl->currentDrawables[tag-1]; + } +} + +/*****************************************************************************/ + +static void StopUsingContext(__GLXcontext *glxc) +{ + if (glxc) { + if (glxc == __glXLastContext) { + /* Tell server GL library */ + __glXLastContext = 0; + } + glxc->isCurrent = GL_FALSE; + if (!glxc->idExists) { + __glXFreeContext(glxc); + } + } +} + +static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) +{ + glxc->isCurrent = GL_TRUE; +} + +/*****************************************************************************/ +/* +** Make an OpenGL context and drawable current. +*/ +static int MakeCurrent(__GLXclientState *cl, + GLXDrawable drawable, + GLXDrawable readdrawable, + GLXContextID context, + GLXContextTag oldContextTag) +{ + ClientPtr client = cl->client; + DrawablePtr pDraw = NULL; + DrawablePtr pReadDraw = NULL; + xGLXMakeCurrentReadSGIReply new_reply; + xGLXMakeCurrentReq *be_req; + xGLXMakeCurrentReply be_reply; + xGLXMakeContextCurrentReq *be_new_req; + xGLXMakeContextCurrentReply be_new_reply; + GLXDrawable drawId = drawable; + GLXDrawable readId = readdrawable; + GLXContextID contextId = context; + __GLXpixmap *pGlxPixmap = 0; + __GLXpixmap *pReadGlxPixmap = 0; + __GLXcontext *glxc, *prevglxc; + GLXContextTag tag = oldContextTag; + WindowPtr pWin = NULL; + WindowPtr pReadWin = NULL; + __glXWindow *pGlxWindow = NULL; + __glXWindow *pGlxReadWindow = NULL; + __glXPbuffer *pGlxPbuffer = NULL; + __glXPbuffer *pGlxReadPbuffer = NULL; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; + PanoramiXRes *pXinReadDraw = NULL; +#endif + int from_screen = 0; + int to_screen = 0; + int s, rc; + + /* + ** If one is None and the other isn't, it's a bad match. + */ + if ((drawId == None && contextId != None) || + (drawId != None && contextId == None)) { + return BadMatch; + } + + /* + ** Lookup old context. If we have one, it must be in a usable state. + */ + if (tag != 0) { + prevglxc = __glXLookupContextByTag(cl, tag); + if (!prevglxc) { + /* + ** Tag for previous context is invalid. + */ + return __glXBadContextTag; + } + } else { + prevglxc = 0; + } + + /* + ** Lookup new context. It must not be current for someone else. + */ + if (contextId != None) { + dixLookupResourceByType((pointer*) &glxc, contextId, __glXContextRes, + NullClient, DixUnknownAccess); + if (!glxc) { + client->errorValue = contextId; + return __glXBadContext; + } + if ((glxc != prevglxc) && glxc->isCurrent) { + /* Context is current to somebody else */ + return BadAccess; + } + } else { + /* Switching to no context. Ignore new drawable. */ + glxc = 0; + } + + if (drawId != None) { + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); + if (rc == Success) { + if (pDraw->type == DRAWABLE_WINDOW) { + /* + ** Drawable is an X Window. + */ + VisualID vid; + pWin = (WindowPtr)pDraw; + vid = wVisual(pWin); + + new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); + new_reply.writeType = GLX_WINDOW_TYPE; + + /* + ** Check if window and context are similar. + */ + if ((vid != glxc->pVisual->vid) || + (pWin->drawable.pScreen != glxc->pScreen)) { + client->errorValue = drawId; + return BadMatch; + } + + from_screen = to_screen = pWin->drawable.pScreen->myNum; + + } else { + /* + ** An X Pixmap is not allowed as a parameter (a GLX Pixmap + ** is, but it must first be created with glxCreateGLXPixmap). + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + if (!pDraw) { + dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, + __glXPixmapRes, NullClient, + DixUnknownAccess); + if (pGlxPixmap) { + /* + ** Check if pixmap and context are similar. + */ + if (pGlxPixmap->pScreen != glxc->pScreen || + pGlxPixmap->pGlxVisual != glxc->pGlxVisual) { + client->errorValue = drawId; + return BadMatch; + } + pDraw = pGlxPixmap->pDraw; + + new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : + pGlxPixmap->pGlxVisual->vid); + + new_reply.writeType = GLX_PIXMAP_TYPE; + + from_screen = to_screen = pGlxPixmap->pScreen->myNum; + + } + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, drawId, + __glXWindowRes, NullClient, + DixUnknownAccess); + if (pGlxWindow) { + /* + ** Drawable is a GLXWindow. + ** + ** Check if GLX window and context are similar. + */ + if (pGlxWindow->pScreen != glxc->pScreen || + pGlxWindow->pGlxFBConfig != glxc->pFBConfig) { + client->errorValue = drawId; + return BadMatch; + } + + pDraw = pGlxWindow->pDraw; + new_reply.writeVid = pGlxWindow->pGlxFBConfig->id; + new_reply.writeType = GLX_GLXWINDOW_TYPE; + } + + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxPbuffer, drawId, + __glXPbufferRes, NullClient, + DixUnknownAccess); + if (pGlxPbuffer) { + if (pGlxPbuffer->pScreen != glxc->pScreen || + pGlxPbuffer->pFBConfig != glxc->pFBConfig) { + client->errorValue = drawId; + return BadMatch; + } + + pDraw = (DrawablePtr)pGlxPbuffer; + new_reply.writeVid = pGlxPbuffer->pFBConfig->id; + new_reply.writeType = GLX_PBUFFER_TYPE; + } + } + + if (!pDraw) { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + } else { + pDraw = 0; + } + + if (readId != None && readId != drawId ) { + rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess); + if (rc == Success) { + if (pReadDraw->type == DRAWABLE_WINDOW) { + /* + ** Drawable is an X Window. + */ + VisualID vid; + pReadWin = (WindowPtr)pDraw; + vid = wVisual(pReadWin); + + new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); + new_reply.readType = GLX_WINDOW_TYPE; + + /* + ** Check if window and context are similar. + */ + if ((vid != glxc->pVisual->vid) || + (pReadWin->drawable.pScreen != glxc->pScreen)) { + client->errorValue = readId; + return BadMatch; + } + + } else { + + /* + ** An X Pixmap is not allowed as a parameter (a GLX Pixmap + ** is, but it must first be created with glxCreateGLXPixmap). + */ + client->errorValue = readId; + return __glXBadDrawable; + } + } + + if (!pReadDraw) { + dixLookupResourceByType((pointer*) &pReadGlxPixmap, readId, + __glXPixmapRes, NullClient, + DixUnknownAccess); + if (pReadGlxPixmap) { + /* + ** Check if pixmap and context are similar. + */ + if (pReadGlxPixmap->pScreen != glxc->pScreen || + pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) { + client->errorValue = readId; + return BadMatch; + } + pReadDraw = pReadGlxPixmap->pDraw; + + new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : + pReadGlxPixmap->pGlxVisual->vid ); + new_reply.readType = GLX_PIXMAP_TYPE; + + } + } + + if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxReadWindow, readId, + __glXWindowRes, NullClient, + DixUnknownAccess); + if (pGlxReadWindow) { + /* + ** Drawable is a GLXWindow. + ** + ** Check if GLX window and context are similar. + */ + if (pGlxReadWindow->pScreen != glxc->pScreen || + pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) { + client->errorValue = readId; + return BadMatch; + } + + pReadDraw = pGlxReadWindow->pDraw; + new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id; + new_reply.readType = GLX_GLXWINDOW_TYPE; + } + } + + if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxReadPbuffer, readId, + __glXPbufferRes, NullClient, + DixUnknownAccess); + if (pGlxReadPbuffer) { + if (pGlxReadPbuffer->pScreen != glxc->pScreen || + pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) { + client->errorValue = drawId; + return BadMatch; + } + + pReadDraw = (DrawablePtr)pGlxReadPbuffer; + new_reply.readVid = pGlxReadPbuffer->pFBConfig->id; + new_reply.readType = GLX_PBUFFER_TYPE; + } + } + + if (!pReadDraw) { + /* + ** Drawable is neither a Window nor a GLXPixmap. + */ + client->errorValue = readId; + return __glXBadDrawable; + } + + } else { + pReadDraw = pDraw; + pReadGlxPixmap = pGlxPixmap; + pReadWin = pWin; + new_reply.readVid = new_reply.writeVid; + new_reply.readType = new_reply.writeType; + } + + if (prevglxc) { + + if (prevglxc->pGlxPixmap) { + /* + ** The previous drawable was a glx pixmap, release it. + */ + prevglxc->pGlxPixmap->refcnt--; + __glXFreeGLXPixmap( prevglxc->pGlxPixmap ); + prevglxc->pGlxPixmap = 0; + } + + if (prevglxc->pGlxReadPixmap) { + /* + ** The previous drawable was a glx pixmap, release it. + */ + prevglxc->pGlxReadPixmap->refcnt--; + __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap ); + prevglxc->pGlxReadPixmap = 0; + } + + if (prevglxc->pGlxWindow) { + /* + ** The previous drawable was a glx window, release it. + */ + prevglxc->pGlxWindow->refcnt--; + __glXFreeGLXWindow( prevglxc->pGlxWindow ); + prevglxc->pGlxWindow = 0; + } + + if (prevglxc->pGlxReadWindow) { + /* + ** The previous drawable was a glx window, release it. + */ + prevglxc->pGlxReadWindow->refcnt--; + __glXFreeGLXWindow( prevglxc->pGlxReadWindow ); + prevglxc->pGlxReadWindow = 0; + } + + if (prevglxc->pGlxPbuffer) { + /* + ** The previous drawable was a glx Pbuffer, release it. + */ + prevglxc->pGlxPbuffer->refcnt--; + __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer ); + prevglxc->pGlxPbuffer = 0; + } + + if (prevglxc->pGlxReadPbuffer) { + /* + ** The previous drawable was a glx Pbuffer, release it. + */ + prevglxc->pGlxReadPbuffer->refcnt--; + __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer ); + prevglxc->pGlxReadPbuffer = 0; + } + + ChangeCurrentContext(cl, glxc, tag); + ChangeCurrentContext(cl, glxc, tag); + StopUsingContext(prevglxc); + } else { + tag = AddCurrentContext(cl, glxc, pDraw); + } + if (glxc) { + + glxc->pGlxPixmap = pGlxPixmap; + glxc->pGlxReadPixmap = pReadGlxPixmap; + glxc->pGlxWindow = pGlxWindow; + glxc->pGlxReadWindow = pGlxReadWindow; + glxc->pGlxPbuffer = pGlxPbuffer; + glxc->pGlxReadPbuffer = pGlxReadPbuffer; + + if (pGlxPixmap) { + pGlxPixmap->refcnt++; + } + + if (pReadGlxPixmap) { + pReadGlxPixmap->refcnt++; + } + + if (pGlxWindow) { + pGlxWindow->refcnt++; + } + + if (pGlxReadWindow) { + pGlxReadWindow->refcnt++; + } + + if (pGlxPbuffer) { + pGlxPbuffer->refcnt++; + } + + if (pGlxReadPbuffer) { + pGlxReadPbuffer->refcnt++; + } + + StartUsingContext(cl, glxc); + new_reply.contextTag = tag; + } else { + new_reply.contextTag = 0; + } + new_reply.length = 0; + new_reply.type = X_Reply; + new_reply.sequenceNumber = client->sequence; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + + if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) { + dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } + + if (pReadDraw && pReadDraw != pDraw && + new_reply.readType != GLX_PBUFFER_TYPE) { + dixLookupResourceByClass((pointer*) &pXinReadDraw, + pReadDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } + else { + pXinReadDraw = pXinDraw; + } + } +#endif + + + /* send the MakeCurrent request to all required + * back-end servers. + */ + for (s = from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + unsigned int be_draw = None; + unsigned int be_read_draw = None; + + if (pGlxPixmap) { + be_draw = pGlxPixmap->be_xids[s]; + } + else if (pGlxPbuffer) { + be_draw = pGlxPbuffer->be_xids[s]; + } +#ifdef PANORAMIX + else if (pXinDraw) { + dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); + } +#endif + else if (pGlxWindow) { + pWin = (WindowPtr)pGlxWindow->pDraw; + } + + if (pWin && be_draw == None) { + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_draw) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + + /* + * Before sending the MakeCurrent request - sync the + * X11 connection to the back-end servers to make sure + * that drawable is already created + */ + dmxSync( dmxScreen, 1 ); + + if (drawId == readId) { + LockDisplay(dpy); + GetReq(GLXMakeCurrent, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXMakeCurrent; + be_req->drawable = be_draw; + be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); + be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); + if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) { + + /* The make current failed */ + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + UnlockDisplay(dpy); + SyncHandle(); + + SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag ); + } + else { + + if (pReadGlxPixmap) { + be_read_draw = pReadGlxPixmap->be_xids[s]; + } + else if (pGlxReadPbuffer) { + be_read_draw = pGlxReadPbuffer->be_xids[s]; + } +#ifdef PANORAMIX + else if (pXinReadDraw) { + dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client, + DixReadAccess); + } +#endif + else if (pGlxReadWindow) { + pReadWin = (WindowPtr)pGlxReadWindow->pDraw; + } + + if (pReadWin && be_read_draw == None) { + be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; + if (!be_read_draw) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pReadWin, TRUE ); + be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; + dmxSync( dmxScreen, 1 ); + } + } + + if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { + LockDisplay(dpy); + GetReq(GLXMakeContextCurrent, be_new_req); + be_new_req->reqType = dmxScreen->glxMajorOpcode; + be_new_req->glxCode = X_GLXMakeContextCurrent; + be_new_req->drawable = be_draw; + be_new_req->readdrawable = be_read_draw; + be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); + be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); + if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) { + + /* The make current failed */ + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + UnlockDisplay(dpy); + SyncHandle(); + + SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag ); + } + else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) { + xGLXMakeCurrentReadSGIReq *ext_req; + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXMakeCurrentReadSGIReply ext_reply; + + LockDisplay(dpy); + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq, + vpreq); + ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq; + ext_req->reqType = dmxScreen->glxMajorOpcode; + ext_req->glxCode = X_GLXVendorPrivateWithReply; + ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI; + ext_req->drawable = be_draw; + ext_req->readable = be_read_draw; + ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); + ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); + if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) { + + /* The make current failed */ + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + UnlockDisplay(dpy); + SyncHandle(); + + SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag ); + + } + else { + return BadMatch; + } + } + + XFlush( dpy ); + } + + if (client->swapped) { + __glXSwapMakeCurrentReply(client, &new_reply); + } else { + WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply); + } + + return Success; +} + +int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; + + return( MakeCurrent(cl, req->drawable, req->drawable, + req->context, req->oldContextTag ) ); +} + +int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; + + return( MakeCurrent(cl, req->drawable, req->readdrawable, + req->context, req->oldContextTag ) ); +} + +int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; + + return( MakeCurrent(cl, req->drawable, req->readable, + req->context, req->oldContextTag ) ); +} + +int __glXIsDirect(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; + xGLXIsDirectReply reply; + __GLXcontext *glxc; + + /* + ** Find the GL context. + */ + dixLookupResourceByType((pointer*) &glxc, req->context, __glXContextRes, + NullClient, DixUnknownAccess); + if (!glxc) { + client->errorValue = req->context; + return __glXBadContext; + } + + reply.isDirect = 0; + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __glXSwapIsDirectReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); + } + + return Success; +} + +int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; +/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */ + xGLXQueryVersionReply reply; + + /* + ** Server should take into consideration the version numbers sent by the + ** client if it wants to work with older clients; however, in this + ** implementation the server just returns its version number. + */ + reply.majorVersion = __glXVersionMajor; + reply.minorVersion = __glXVersionMinor; + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __glXSwapQueryVersionReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); + } + return Success; +} + +int __glXWaitGL(__GLXclientState *cl, GLbyte *pc) +{ + xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; + xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc; + int from_screen = 0; + int to_screen = 0; + int s; + __GLXcontext *glxc = NULL; + + if (req->contextTag != 0) { + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (glxc) { + from_screen = to_screen = glxc->pScreen->myNum; + } + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXWaitGL,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXWaitGL; + be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + UnlockDisplay(dpy); + SyncHandle(); + + XSync(dpy, False); + } + + return Success; +} + +int __glXWaitX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXWaitXReq *req = (xGLXWaitXReq *)pc; + xGLXWaitXReq *be_req; + int from_screen = 0; + int to_screen = 0; + int s; + __GLXcontext *glxc = NULL; + + if (req->contextTag != 0) { + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (glxc) { + from_screen = to_screen = glxc->pScreen->myNum; + } + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXWaitX,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXWaitX; + be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + UnlockDisplay(dpy); + SyncHandle(); + + XFlush( dpy ); + } + + return Success; +} + +int __glXCopyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCopyContextReq *be_req; + xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; + GLXContextID source = req->source; + GLXContextID dest = req->dest; + GLXContextTag tag = req->contextTag; + unsigned long mask = req->mask; + __GLXcontext *src, *dst; + int s; + int from_screen = 0; + int to_screen = 0; + + /* + ** Check that each context exists. + */ + dixLookupResourceByType((pointer*) &src, source, __glXContextRes, + NullClient, DixUnknownAccess); + if (!src) { + client->errorValue = source; + return __glXBadContext; + } + dixLookupResourceByType((pointer*) &dst, dest, __glXContextRes, + NullClient, DixUnknownAccess); + if (!dst) { + client->errorValue = dest; + return __glXBadContext; + } + + /* + ** They must be in the same address space, and same screen. + */ + if (src->pGlxScreen != dst->pGlxScreen) { + client->errorValue = source; + return BadMatch; + } + + /* + ** The destination context must not be current for any client. + */ + if (dst->isCurrent) { + client->errorValue = dest; + return BadAccess; + } + + if (tag) { + __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); + + if (!tagcx) { + return __glXBadContextTag; + } + if (tagcx != src) { + /* + ** This would be caused by a faulty implementation of the client + ** library. + */ + return BadMatch; + } + } + + from_screen = to_screen = src->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXCopyContext,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCopyContext; + be_req->source = (unsigned int)src->real_ids[s-from_screen]; + be_req->dest = (unsigned int)dst->real_ids[s-from_screen]; + be_req->mask = mask; + be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; + xGLXGetVisualConfigsReply reply; + __GLXscreenInfo *pGlxScreen; + __GLXvisualConfig *pGlxVisual; + CARD32 buf[__GLX_TOTAL_CONFIG]; + unsigned int screen; + int i, p; + + screen = req->screen; + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + pGlxScreen = &__glXActiveScreens[screen]; + + reply.numVisuals = pGlxScreen->numGLXVisuals; + reply.numProps = __GLX_TOTAL_CONFIG; + reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 * + __GLX_TOTAL_CONFIG) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); + + for (i=0; i < pGlxScreen->numVisuals; i++) { + pGlxVisual = &pGlxScreen->pGlxVisual[i]; + if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) { + /* not a usable visual */ + continue; + } + p = 0; + buf[p++] = pGlxVisual->vid; + buf[p++] = pGlxVisual->class; + buf[p++] = pGlxVisual->rgba; + + buf[p++] = pGlxVisual->redSize; + buf[p++] = pGlxVisual->greenSize; + buf[p++] = pGlxVisual->blueSize; + buf[p++] = pGlxVisual->alphaSize; + buf[p++] = pGlxVisual->accumRedSize; + buf[p++] = pGlxVisual->accumGreenSize; + buf[p++] = pGlxVisual->accumBlueSize; + buf[p++] = pGlxVisual->accumAlphaSize; + + buf[p++] = pGlxVisual->doubleBuffer; + buf[p++] = pGlxVisual->stereo; + + buf[p++] = pGlxVisual->bufferSize; + buf[p++] = pGlxVisual->depthSize; + buf[p++] = pGlxVisual->stencilSize; + buf[p++] = pGlxVisual->auxBuffers; + buf[p++] = pGlxVisual->level; + /* + ** Add token/value pairs for extensions. + */ + buf[p++] = GLX_VISUAL_CAVEAT_EXT; + buf[p++] = pGlxVisual->visualRating; + buf[p++] = GLX_TRANSPARENT_TYPE_EXT; + buf[p++] = pGlxVisual->transparentPixel; + buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; + buf[p++] = pGlxVisual->transparentRed; + buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; + buf[p++] = pGlxVisual->transparentGreen; + buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; + buf[p++] = pGlxVisual->transparentBlue; + buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; + buf[p++] = pGlxVisual->transparentAlpha; + buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; + buf[p++] = pGlxVisual->transparentIndex; + buf[p++] = GLX_SAMPLES_SGIS; + buf[p++] = pGlxVisual->multiSampleSize; + buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; + buf[p++] = pGlxVisual->nMultiSampleBuffers; + buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; + buf[p++] = pGlxVisual->visualSelectGroup; + + WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, + (char *)buf); + } + return Success; +} + +/* +** Create a GLX Pixmap from an X Pixmap. +*/ +static int CreateGLXPixmap(__GLXclientState *cl, + VisualID visual, GLXFBConfigID fbconfigId, + int screenNum, XID pixmapId, XID glxpixmapId ) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPixmapReq *be_req; + xGLXCreatePixmapReq *be_new_req; + DrawablePtr pDraw; + ScreenPtr pScreen; + VisualPtr pVisual; + __GLXpixmap *pGlxPixmap; + __GLXscreenInfo *pGlxScreen; + __GLXvisualConfig *pGlxVisual; + __GLXFBConfig *pFBConfig; + int i, s, rc; + int from_screen, to_screen; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; +#endif + + rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP, + DixAddAccess); + if (rc != Success) + return rc; + + /* + ** Check if screen of visual matches screen of pixmap. + */ + pScreen = pDraw->pScreen; + if (screenNum != pScreen->myNum) { + return BadMatch; + } + + if (fbconfigId == 0 && visual == 0) { + return BadValue; + } + + if (fbconfigId != None) { + pFBConfig = glxLookupFBConfig( fbconfigId ); + if (!pFBConfig) { + client->errorValue = fbconfigId; + return BadValue; + } + visual = pFBConfig->associatedVisualId; + } + else { + pFBConfig = NULL; + } + + if (visual != None) { + /* + ** Find the VisualRec for this visual. + */ + pVisual = pScreen->visuals; + for (i=0; i < pScreen->numVisuals; i++, pVisual++) { + if (pVisual->vid == visual) { + break; + } + } + if (i == pScreen->numVisuals) { + client->errorValue = visual; + return BadValue; + } + /* + ** Check if depth of visual matches depth of pixmap. + */ + if (pVisual->nplanes != pDraw->depth) { + client->errorValue = visual; + return BadMatch; + } + + /* + ** Get configuration of the visual. + */ + pGlxScreen = &__glXActiveScreens[screenNum]; + pGlxVisual = pGlxScreen->pGlxVisual; + for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { + if (pGlxVisual->vid == visual) { + break; + } + } + if (i == pGlxScreen->numVisuals) { + /* + ** Visual not support on this screen by this OpenGL implementation. + */ + client->errorValue = visual; + return BadValue; + } + + + /* find the FBConfig for that visual (if any) */ + if ( pFBConfig == NULL ) { + pFBConfig = glxLookupFBConfigByVID( visual ); + + if ( pFBConfig == NULL ) { + /* + * visual does not have an FBConfig ??? + client->errorValue = visual; + return BadValue; + */ + } + } + } + else { + pVisual = NULL; + pGlxVisual = NULL; + pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum]; + } + + pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap)); + if (!pGlxPixmap) { + return BadAlloc; + } + pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens); + if (!pGlxPixmap->be_xids) { + free( pGlxPixmap ); + return BadAlloc; + } + + pGlxPixmap->pDraw = pDraw; + pGlxPixmap->pGlxScreen = pGlxScreen; + pGlxPixmap->pGlxVisual = pGlxVisual; + pGlxPixmap->pFBConfig = pFBConfig; + pGlxPixmap->pScreen = pScreen; + pGlxPixmap->idExists = True; + pGlxPixmap->refcnt = 0; + + /* + ** Bump the ref count on the X pixmap so it won't disappear. + */ + ((PixmapPtr) pDraw)->refcnt++; + + /* + * send the request to the back-end server(s) + */ + from_screen = to_screen = screenNum; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + + dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + Pixmap be_pixmap; + DrawablePtr pRealDraw = pDraw; + +#ifdef PANORAMIX + if (pXinDraw) { + dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0, + DixAddAccess); + } +#endif + + be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap; + + /* make sure pixmap already created on back-end */ + dmxSync( dmxScreen, 1 ); + + if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); + + LockDisplay(dpy); + pGlxPixmap->be_xids[s] = XAllocID(dpy); + GetReq(GLXCreatePixmap,be_new_req); + be_new_req->reqType = dmxScreen->glxMajorOpcode; + be_new_req->glxCode = X_GLXCreatePixmap; + be_new_req->screen = DefaultScreen(dpy); + be_new_req->fbconfig = be_FBConfig->id; + be_new_req->pixmap = (unsigned int)be_pixmap; + be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + be_new_req->numAttribs = 0; + UnlockDisplay(dpy); + SyncHandle(); + } + else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) { + __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); + xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req; + xGLXVendorPrivateReq *vpreq; + + LockDisplay(dpy); + pGlxPixmap->be_xids[s] = XAllocID(dpy); + GetReqExtra(GLXVendorPrivate, + sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq, + vpreq); + ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq; + ext_req->reqType = dmxScreen->glxMajorOpcode; + ext_req->glxCode = X_GLXVendorPrivate; + ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; + ext_req->screen = DefaultScreen(dpy); + ext_req->fbconfig = be_FBConfig->id; + ext_req->pixmap = (unsigned int)be_pixmap; + ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + else if (pGlxVisual) { + LockDisplay(dpy); + pGlxPixmap->be_xids[s] = XAllocID(dpy); + GetReq(GLXCreateGLXPixmap,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCreateGLXPixmap; + be_req->screen = DefaultScreen(dpy); + be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList( + pGlxVisual, + dmxScreen->glxVisuals, + dmxScreen->numGlxVisuals ); + be_req->pixmap = (unsigned int)be_pixmap; + be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + else { + client->errorValue = ( visual ? visual : fbconfigId ); + free( pGlxPixmap ); + return BadValue; + } + + XFlush( dpy ); + } + + if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) { + free( pGlxPixmap ); + return BadAlloc; + } + + return Success; +} + +int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + + return( CreateGLXPixmap(cl, req->visual, None, + req->screen, req->pixmap, req->glxpixmap) ); +} + +int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + + return( CreateGLXPixmap(cl, None, req->fbconfig, + req->screen, req->pixmap, req->glxpixmap) ); +} + +int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; + XID glxpixmap = req->glxpixmap; + __GLXpixmap *pGlxPixmap; + int s; + int from_screen, to_screen; + + /* + ** Check if it's a valid GLX pixmap. + */ + dixLookupResourceByType((pointer*) &pGlxPixmap, glxpixmap, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (!pGlxPixmap) { + client->errorValue = glxpixmap; + return __glXBadPixmap; + } + FreeResource(glxpixmap, FALSE); + + /* + * destroy the pixmap on the back-end server(s). + */ + from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + /* make sure pixmap exist in back-end */ + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXDestroyGLXPixmap,req); + req->reqType = dmxScreen->glxMajorOpcode; + req->glxCode = X_GLXDestroyGLXPixmap; + req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + + + return Success; +} + +/*****************************************************************************/ + +/* +** NOTE: There is no portable implementation for swap buffers as of +** this time that is of value. Consequently, this code must be +** implemented by somebody other than SGI. +*/ +int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag) +{ + ClientPtr client = cl->client; + DrawablePtr pDraw; + xGLXSwapBuffersReq *be_req; + WindowPtr pWin = NULL; + __GLXpixmap *pGlxPixmap = NULL; + __GLXcontext *glxc = NULL; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; +#endif + __glXWindow *pGlxWindow = NULL; + int from_screen = 0; + int to_screen = 0; + int s, rc; + + /* + ** Check that the GLX drawable is valid. + */ + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); + if (rc == Success) { + from_screen = to_screen = pDraw->pScreen->myNum; + + if (pDraw->type == DRAWABLE_WINDOW) { + /* + ** Drawable is an X window. + */ + pWin = (WindowPtr)pDraw; + } else { + /* + ** Drawable is an X pixmap, which is not allowed. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + if (!pDraw) { + dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) { + /* + ** Drawable is a GLX pixmap. + */ + pDraw = pGlxPixmap->pDraw; + from_screen = to_screen = pGlxPixmap->pScreen->myNum; + } + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, drawId, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) { + /* + ** Drawable is a GLXWindow. + */ + pDraw = pGlxWindow->pDraw; + from_screen = to_screen = pGlxWindow->pScreen->myNum; + } + } + + if (!pDraw) { + /* + ** Drawable is neither a X window nor a GLX pixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXBadContextTag; + } + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } +#endif + + /* If requested, send a glFinish to all back-end servers before swapping. */ + if (dmxGLXFinishSwap) { + for (s=from_screen; s<=to_screen; s++) { + Display *dpy = GetBackEndDisplay(cl,s); + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + xGLXSingleReq *finishReq; + xGLXSingleReply reply; + +#define X_GLXSingle 0 /* needed by GetReq below */ + + LockDisplay(dpy); + GetReq(GLXSingle,finishReq); + finishReq->reqType = dmxScreen->glxMajorOpcode; + finishReq->glxCode = X_GLsop_Finish; + finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0); + (void) _XReply(dpy, (xReply*) &reply, 0, False); + UnlockDisplay(dpy); + SyncHandle(); + } + } + + /* If requested, send an XSync to all back-end servers before swapping. */ + if (dmxGLXSyncSwap) { + for (s=from_screen; s<=to_screen; s++) + XSync(GetBackEndDisplay(cl,s), False); + } + + + /* send the SwapBuffers request to all back-end servers */ + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + unsigned int be_draw = 0; + + if (pGlxPixmap) { + be_draw = (unsigned int)pGlxPixmap->be_xids[s]; + } +#ifdef PANORAMIX + else if (pXinDraw) { + dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); + } +#endif + else if (pGlxWindow) { + pWin = (WindowPtr)pGlxWindow->pDraw; + } + + if (pWin && !be_draw) { + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_draw) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXSwapBuffers,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXSwapBuffers; + be_req->drawable = be_draw; + be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 ); + UnlockDisplay(dpy); + SyncHandle(); + XFlush(dpy); + } + + return Success; +} + +int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + DrawablePtr pDraw; + xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; + GLXContextTag tag = req->contextTag; + XID drawId = req->drawable; + __GLXpixmap *pGlxPixmap = NULL; + __GLXcontext *glxc = NULL; + __glXWindow *pGlxWindow = NULL; + int rc; + + /* + ** Check that the GLX drawable is valid. + */ + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); + if (rc == Success) { + if (pDraw->type != DRAWABLE_WINDOW) { + /* + ** Drawable is an X pixmap, which is not allowed. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + if (!pDraw) { + dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) { + /* + ** Drawable is a GLX pixmap. + */ + pDraw = pGlxPixmap->pDraw; + } + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, drawId, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) { + /* + ** Drawable is a GLXWindow. + */ + pDraw = pGlxWindow->pDraw; + } + } + + if (!pDraw) { + /* + ** Drawable is neither a X window nor a GLX pixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXBadContextTag; + } + } + + if (pDraw && + pDraw->type == DRAWABLE_WINDOW && + DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) { + return SGSwapBuffers(cl, drawId, tag, pDraw); + } + + return __glXDoSwapBuffers(cl, drawId, tag); +} + + +/************************************************************************/ + +/* +** Render and Renderlarge are not in the GLX API. They are used by the GLX +** client library to send batches of GL rendering commands. +*/ + +/* +** Execute all the drawing commands in a request. +*/ +int __glXRender(__GLXclientState *cl, GLbyte *pc) +{ + xGLXRenderReq *req; + xGLXRenderReq *be_req; + int size; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int s; + + /* + ** NOTE: much of this code also appears in the byteswapping version of this + ** routine, __glXSwapRender(). Any changes made here should also be + ** duplicated there. + */ + + req = (xGLXRenderReq *) pc; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXRenderReq; + size = (req->length << 2) - sz_xGLXRenderReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXRender,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXRender; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + _XSend(dpy, (const char *)pc, size); + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +/* +** Execute a large rendering request (one that spans multiple X requests). +*/ +int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc) +{ + xGLXRenderLargeReq *req; + xGLXRenderLargeReq *be_req; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int s; + + /* + ** NOTE: much of this code also appears in the byteswapping version of this + ** routine, __glXSwapRenderLarge(). Any changes made here should also be + ** duplicated there. + */ + + req = (xGLXRenderLargeReq *) pc; + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXRenderLargeReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + GetReq(GLXRenderLarge,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXRenderLarge; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + be_req->length = req->length; + be_req->requestNumber = req->requestNumber; + be_req->requestTotal = req->requestTotal; + be_req->dataBytes = req->dataBytes; + Data(dpy, (const char *)pc, req->dataBytes); + UnlockDisplay(dpy); + SyncHandle(); + + } + + return Success; +} + + +/************************************************************************/ + +int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req; + + req = (xGLXVendorPrivateReq *) pc; + + switch( req->vendorCode ) { + + case X_GLvop_DeleteTexturesEXT: + return __glXVForwardSingleReq( cl, pc ); + break; + + case X_GLXvop_SwapIntervalSGI: + if (glxIsExtensionSupported("SGI_swap_control")) { + return __glXVForwardSingleReq( cl, pc ); + } + else { + return Success; + } + break; + +#if 0 /* glx 1.3 */ + case X_GLXvop_CreateGLXVideoSourceSGIX: + break; + case X_GLXvop_DestroyGLXVideoSourceSGIX: + break; + case X_GLXvop_CreateGLXPixmapWithConfigSGIX: + break; + case X_GLXvop_DestroyGLXPbufferSGIX: + break; + case X_GLXvop_ChangeDrawableAttributesSGIX: + break; +#endif + + case X_GLXvop_BindSwapBarrierSGIX: + return __glXBindSwapBarrierSGIX( cl, pc ); + break; + + case X_GLXvop_JoinSwapGroupSGIX: + return __glXJoinSwapGroupSGIX( cl, pc ); + break; + + case X_GLXvop_CreateContextWithConfigSGIX: + return __glXCreateContextWithConfigSGIX( cl, pc ); + break; + + default: + /* + ** unsupported private request + */ + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + } + + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + +} + +int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateWithReplyReq *req; + + req = (xGLXVendorPrivateWithReplyReq *) pc; + + switch( req->vendorCode ) { + + case X_GLvop_GetConvolutionFilterEXT: + case X_GLvop_GetConvolutionParameterfvEXT: + case X_GLvop_GetConvolutionParameterivEXT: + case X_GLvop_GetSeparableFilterEXT: + case X_GLvop_GetHistogramEXT: + case X_GLvop_GetHistogramParameterivEXT: + case X_GLvop_GetMinmaxEXT: + case X_GLvop_GetMinmaxParameterfvEXT: + case X_GLvop_GetMinmaxParameterivEXT: + case X_GLvop_AreTexturesResidentEXT: + case X_GLvop_IsTextureEXT: + return( __glXVForwardPipe0WithReply(cl, pc) ); + break; + + case X_GLvop_GenTexturesEXT: + return( __glXVForwardAllWithReply(cl, pc) ); + break; + + +#if 0 /* glx1.3 */ + case X_GLvop_GetDetailTexFuncSGIS: + case X_GLvop_GetSharpenTexFuncSGIS: + case X_GLvop_GetColorTableSGI: + case X_GLvop_GetColorTableParameterfvSGI: + case X_GLvop_GetColorTableParameterivSGI: + case X_GLvop_GetTexFilterFuncSGIS: + case X_GLvop_GetInstrumentsSGIX: + case X_GLvop_InstrumentsBufferSGIX: + case X_GLvop_PollInstrumentsSGIX: + case X_GLvop_FlushRasterSGIX: + case X_GLXvop_CreateGLXPbufferSGIX: + case X_GLXvop_GetDrawableAttributesSGIX: + case X_GLXvop_QueryHyperpipeNetworkSGIX: + case X_GLXvop_QueryHyperpipeConfigSGIX: + case X_GLXvop_HyperpipeConfigSGIX: + case X_GLXvop_DestroyHyperpipeConfigSGIX: +#endif + case X_GLXvop_QueryMaxSwapBarriersSGIX: + return( __glXQueryMaxSwapBarriersSGIX(cl, pc) ); + break; + + case X_GLXvop_GetFBConfigsSGIX: + return( __glXGetFBConfigsSGIX(cl, pc) ); + break; + + case X_GLXvop_MakeCurrentReadSGI: + return( __glXMakeCurrentReadSGI(cl, pc) ); + break; + + case X_GLXvop_QueryContextInfoEXT: + return( __glXQueryContextInfoEXT(cl,pc) ); + break; + + default: + /* + ** unsupported private request + */ + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + } + +} + +int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; + xGLXQueryExtensionsStringReply reply; + GLint screen; + size_t length; + int len, numbytes; + char *be_buf; + +#ifdef FWD_QUERY_REQ + xGLXQueryExtensionsStringReq *be_req; + xGLXQueryExtensionsStringReply be_reply; + DMXScreenInfo *dmxScreen; + Display *dpy; + int slop; +#endif + + screen = req->screen; + + /* + ** Check if screen exists. + */ + if ((screen < 0) || (screen >= screenInfo.numScreens)) { + client->errorValue = screen; + return BadValue; + } + +#ifdef FWD_QUERY_REQ + dmxScreen = &dmxScreens[screen]; + + /* Send the glXQueryServerString request */ + dpy = GetBackEndDisplay(cl,screen); + LockDisplay(dpy); + GetReq(GLXQueryExtensionsString,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXQueryServerString; + be_req->screen = DefaultScreen(dpy); + _XReply(dpy, (xReply*) &be_reply, 0, False); + len = (int)be_reply.length; + numbytes = (int)be_reply.n; + slop = numbytes * __GLX_SIZE_INT8 & 3; + be_buf = (char *)malloc(numbytes); + if (!be_buf) { + /* Throw data on the floor */ + _XEatData(dpy, len); + } else { + _XRead(dpy, (char *)be_buf, numbytes); + if (slop) _XEatData(dpy,4-slop); + } + UnlockDisplay(dpy); + SyncHandle(); + +#else + + be_buf = __glXGetServerString(GLX_EXTENSIONS); + numbytes = strlen(be_buf) + 1; + len = __GLX_PAD(numbytes) >> 2; + +#endif + + length = len; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = len; + reply.n = numbytes; + + if (client->swapped) { + glxSwapQueryExtensionsStringReply(client, &reply, be_buf); + } else { + WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); + WriteToClient(client, (int)(length << 2), (char *)be_buf); + } + + return Success; +} + +int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; + xGLXQueryServerStringReply reply; + int name; + GLint screen; + size_t length; + int len, numbytes; + char *be_buf; +#ifdef FWD_QUERY_REQ + xGLXQueryServerStringReq *be_req; + xGLXQueryServerStringReply be_reply; + DMXScreenInfo *dmxScreen; + Display *dpy; + int slop; +#endif + + name = req->name; + screen = req->screen; + /* + ** Check if screen exists. + */ + if ((screen < 0) || (screen >= screenInfo.numScreens)) { + client->errorValue = screen; + return BadValue; + } + +#ifdef FWD_QUERY_REQ + dmxScreen = &dmxScreens[screen]; + + /* Send the glXQueryServerString request */ + dpy = GetBackEndDisplay(cl,screen); + LockDisplay(dpy); + GetReq(GLXQueryServerString,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXQueryServerString; + be_req->screen = DefaultScreen(dpy); + be_req->name = name; + _XReply(dpy, (xReply*) &be_reply, 0, False); + len = (int)be_reply.length; + numbytes = (int)be_reply.n; + slop = numbytes * __GLX_SIZE_INT8 & 3; + be_buf = (char *)malloc(numbytes); + if (!be_buf) { + /* Throw data on the floor */ + _XEatData(dpy, len); + } else { + _XRead(dpy, (char *)be_buf, numbytes); + if (slop) _XEatData(dpy,4-slop); + } + UnlockDisplay(dpy); + SyncHandle(); + +#else + be_buf = __glXGetServerString(name); + numbytes = strlen(be_buf) + 1; + len = __GLX_PAD(numbytes) >> 2; +#endif + + length = len; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = length; + reply.n = numbytes; + + if (client->swapped) { + glxSwapQueryServerStringReply(client, &reply, be_buf); + } else { + WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); + WriteToClient(client, (int)(length << 2), be_buf); + } + + return Success; +} + +int __glXClientInfo(__GLXclientState *cl, GLbyte *pc) +{ + xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; + xGLXClientInfoReq *be_req; + const char *buf; + int from_screen = 0; + int to_screen = 0; + int s; + + cl->GLClientmajorVersion = req->major; + cl->GLClientminorVersion = req->minor; + free(cl->GLClientextensions); + buf = (const char *)(req+1); + cl->GLClientextensions = strdup(buf); + + to_screen = screenInfo.numScreens - 1; + + for (s=from_screen; s<=to_screen; s++) + { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXClientInfo,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXClientInfo; + be_req->major = req->major; + be_req->minor = req->minor; + be_req->length = req->length; + be_req->numbytes = req->numbytes; + Data(dpy, buf, req->numbytes); + + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +int __glXUseXFont(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXUseXFontReq *req; + xGLXUseXFontReq *be_req; + FontPtr pFont; + __GLXcontext *glxc = NULL; + int from_screen = 0; + int to_screen = 0; + int s; + dmxFontPrivPtr pFontPriv; + DMXScreenInfo *dmxScreen; + Display *dpy; + + req = (xGLXUseXFontReq *) pc; + + if (req->contextTag != 0) { + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (glxc) { + from_screen = to_screen = glxc->pScreen->myNum; + } + } + + /* + ** Font can actually be either the ID of a font or the ID of a GC + ** containing a font. + */ + dixLookupResourceByType((pointer*) &pFont, req->font, RT_FONT, + NullClient, DixUnknownAccess); + if (!pFont) { + GC *pGC; + dixLookupResourceByType((pointer*) &pGC, req->font, + RT_GC, NullClient, + DixUnknownAccess); + if (!pGC) { + client->errorValue = req->font; + return BadFont; + } + pFont = pGC->font; + } + + pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex); + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + + for (s=from_screen; s<=to_screen; s++) { + dmxScreen = &dmxScreens[s]; + dpy = GetBackEndDisplay(cl,s); + + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXUseXFont,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXUseXFont; + be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + be_req->font = pFontPriv->font[s]->fid; + be_req->first = req->first; + be_req->count = req->count; + be_req->listBase = req->listBase; + UnlockDisplay(dpy); + SyncHandle(); + + XSync( dpy, False ); + } + + return Success; +} + +/* + * start GLX 1.3 here + */ + +int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; + xGLXGetFBConfigsReply reply; + __GLXFBConfig *pFBConfig; + CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS]; + int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS; + unsigned int screen = req->screen; + int numFBConfigs, i, p; + __GLXscreenInfo *pGlxScreen; + + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + + pGlxScreen = &__glXActiveScreens[screen]; + numFBConfigs = __glXNumFBConfigs; + + reply.numFBConfigs = numFBConfigs; + reply.numAttribs = numAttribs; + reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + __GLX_SWAP_INT(&reply.numFBConfigs); + __GLX_SWAP_INT(&reply.numAttribs); + } + WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); + + for (i=0; i < numFBConfigs; i++) { + int associatedVisualId = 0; + int drawableTypeIndex; + pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ]; + + p = 0; + /* core attributes */ + buf[p++] = GLX_FBCONFIG_ID; + buf[p++] = pFBConfig->id; + buf[p++] = GLX_BUFFER_SIZE; + buf[p++] = pFBConfig->indexBits; + buf[p++] = GLX_LEVEL; + buf[p++] = pFBConfig->level; + buf[p++] = GLX_DOUBLEBUFFER; + buf[p++] = pFBConfig->doubleBufferMode; + buf[p++] = GLX_STEREO; + buf[p++] = pFBConfig->stereoMode; + buf[p++] = GLX_AUX_BUFFERS; + buf[p++] = pFBConfig->maxAuxBuffers; + buf[p++] = GLX_RED_SIZE; + buf[p++] = pFBConfig->redBits; + buf[p++] = GLX_GREEN_SIZE; + buf[p++] = pFBConfig->greenBits; + buf[p++] = GLX_BLUE_SIZE; + buf[p++] = pFBConfig->blueBits; + buf[p++] = GLX_ALPHA_SIZE; + buf[p++] = pFBConfig->alphaBits; + buf[p++] = GLX_DEPTH_SIZE; + buf[p++] = pFBConfig->depthBits; + buf[p++] = GLX_STENCIL_SIZE; + buf[p++] = pFBConfig->stencilBits; + buf[p++] = GLX_ACCUM_RED_SIZE; + buf[p++] = pFBConfig->accumRedBits; + buf[p++] = GLX_ACCUM_GREEN_SIZE; + buf[p++] = pFBConfig->accumGreenBits; + buf[p++] = GLX_ACCUM_BLUE_SIZE; + buf[p++] = pFBConfig->accumBlueBits; + buf[p++] = GLX_ACCUM_ALPHA_SIZE; + buf[p++] = pFBConfig->accumAlphaBits; + buf[p++] = GLX_RENDER_TYPE; + buf[p++] = pFBConfig->renderType; + buf[p++] = GLX_DRAWABLE_TYPE; + drawableTypeIndex = p; + buf[p++] = pFBConfig->drawableType; + buf[p++] = GLX_X_VISUAL_TYPE; + buf[p++] = pFBConfig->visualType; + buf[p++] = GLX_CONFIG_CAVEAT; + buf[p++] = pFBConfig->visualCaveat; + buf[p++] = GLX_TRANSPARENT_TYPE; + buf[p++] = pFBConfig->transparentType; + buf[p++] = GLX_TRANSPARENT_RED_VALUE; + buf[p++] = pFBConfig->transparentRed; + buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; + buf[p++] = pFBConfig->transparentGreen; + buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; + buf[p++] = pFBConfig->transparentBlue; + buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; + buf[p++] = pFBConfig->transparentAlpha; + buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; + buf[p++] = pFBConfig->transparentIndex; + buf[p++] = GLX_MAX_PBUFFER_WIDTH; + buf[p++] = pFBConfig->maxPbufferWidth; + buf[p++] = GLX_MAX_PBUFFER_HEIGHT; + buf[p++] = pFBConfig->maxPbufferHeight; + buf[p++] = GLX_MAX_PBUFFER_PIXELS; + buf[p++] = pFBConfig->maxPbufferPixels; + + /* + * find the visual of the back-end server and match a visual + * on the proxy. + * do only once - if a visual is not yet associated. + */ + if (pFBConfig->associatedVisualId == (unsigned int)-1) { + DMXScreenInfo *dmxScreen = &dmxScreens[screen]; + __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ]; + __GLXvisualConfig *pGlxVisual = NULL; + int v; + int found = 0; + for (v=0; vnumGlxVisuals; v++) { + if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) { + pGlxVisual = &dmxScreen->glxVisuals[v]; + break; + } + } + + if (pGlxVisual) { + for (v=0; vnumVisuals; v++) { + if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) { + associatedVisualId = pGlxScreen->pGlxVisual[v].vid; + found = 1; + break; + } + } + } + + if (!found) { + associatedVisualId = 0; + pFBConfig->drawableType &= ~(GLX_WINDOW_BIT); + buf[drawableTypeIndex] = pFBConfig->drawableType; + } +#ifdef PANORAMIX + else if (!noPanoramiXExtension) { + /* convert the associated visualId to the panoramix one */ + pFBConfig->associatedVisualId = + PanoramiXTranslateVisualID(screen, v); + } +#endif + } + else { + associatedVisualId = pFBConfig->associatedVisualId; + } + + buf[p++] = GLX_VISUAL_ID; + buf[p++] = associatedVisualId; + + /* SGIS_multisample attributes */ + buf[p++] = GLX_SAMPLES_SGIS; + buf[p++] = pFBConfig->multiSampleSize; + buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; + buf[p++] = pFBConfig->nMultiSampleBuffers; + + /* SGIX_pbuffer specific attributes */ + buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX; + buf[p++] = pFBConfig->optimalPbufferWidth; + buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX; + buf[p++] = pFBConfig->optimalPbufferHeight; + + buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; + buf[p++] = pFBConfig->visualSelectGroup; + + if (client->swapped) { + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs); + } + WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf); + } + return Success; +} + +int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc; + xGLXGetFBConfigsReq new_req; + + new_req.reqType = req->reqType; + new_req.glxCode = req->glxCode; + new_req.length = req->length; + new_req.screen = req->screen; + + return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) ); +} + + +int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; + int screen = req->screen; + GLXFBConfigID fbconfigId = req->fbconfig; + XID windowId = req->window; + XID glxwindowId = req->glxwindow; + DrawablePtr pDraw; + ScreenPtr pScreen; + __glXWindow *pGlxWindow; + __GLXFBConfig *pGlxFBConfig = NULL; + VisualPtr pVisual; + VisualID visId; + int i, rc; + pointer val; + + /* + ** Check if windowId is valid + */ + rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW, + DixAddAccess); + if (rc != Success) + return rc; + + /* + ** Check if screen of window matches screen of fbconfig. + */ + pScreen = pDraw->pScreen; + if (screen != pScreen->myNum) { + return BadMatch; + } + + /* + ** Find the FBConfigRec for this fbconfigid. + */ + if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { + client->errorValue = fbconfigId; + return __glXBadFBConfig; + } + visId = pGlxFBConfig->associatedVisualId; + + /* + ** Check if the fbconfig supports rendering to windows + */ + if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) { + return BadMatch; + } + + if (visId != None) { + /* + ** Check if the visual ID is valid for this screen. + */ + pVisual = pScreen->visuals; + for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { + if (pVisual->vid == visId) { + break; + } + } + if (i == pScreen->numVisuals) { + client->errorValue = visId; + return BadValue; + } + + /* + ** Check if color buffer depth of fbconfig matches depth + ** of window. + */ + if (pVisual->nplanes != pDraw->depth) { + return BadMatch; + } + } else + /* + ** The window was created with no visual that corresponds + ** to fbconfig + */ + return BadMatch; + + /* + ** Check if there is already a fbconfig associated with this window + */ + if (Success == dixLookupResourceByType(&val, + glxwindowId, __glXWindowRes, + NullClient, DixUnknownAccess)) { + client->errorValue = glxwindowId; + return BadAlloc; + } + + pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow)); + if (!pGlxWindow) { + return BadAlloc; + } + + /* + ** Register this GLX window as a resource + */ + if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) { + return BadAlloc; + } + + pGlxWindow->pDraw = pDraw; + pGlxWindow->type = GLX_GLXWINDOW_TYPE; + pGlxWindow->idExists = True; + pGlxWindow->refcnt = 0; + pGlxWindow->pGlxFBConfig = pGlxFBConfig; + pGlxWindow->pScreen = pScreen; + + return Success; +} + +int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; + XID glxwindow = req->glxwindow; + pointer val; + + /* + ** Check if it's a valid GLX window. + */ + if (Success != dixLookupResourceByType(&val, + glxwindow, __glXWindowRes, + NullClient, DixUnknownAccess)) { + client->errorValue = glxwindow; + return __glXBadDrawable; + } + /* + ** The glx window destructor will check whether it's current before + ** freeing anything. + */ + FreeResource(glxwindow, RT_NONE); + + return Success; +} + +int __glXQueryContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + __GLXcontext *ctx; + xGLXQueryContextReq *req; + xGLXQueryContextReply reply; + int nProps; + int *sendBuf, *pSendBuf; + int nReplyBytes; + + req = (xGLXQueryContextReq *)pc; + dixLookupResourceByType((pointer*) &ctx, req->context, __glXContextRes, + NullClient, DixUnknownAccess); + if (!ctx) { + client->errorValue = req->context; + return __glXBadContext; + } + + nProps = 3; + + reply.length = nProps << 1; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.n = nProps; + + nReplyBytes = reply.length << 2; + sendBuf = (int *)malloc(nReplyBytes); + pSendBuf = sendBuf; + *pSendBuf++ = GLX_FBCONFIG_ID; + *pSendBuf++ = (int)(ctx->pFBConfig->id); + *pSendBuf++ = GLX_RENDER_TYPE; + *pSendBuf++ = (int)(ctx->pFBConfig->renderType); + *pSendBuf++ = GLX_SCREEN; + *pSendBuf++ = (int)(ctx->pScreen->myNum); + + if (client->swapped) { + __glXSwapQueryContextReply(client, &reply, sendBuf); + } else { + WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply); + WriteToClient(client, nReplyBytes, (char *)sendBuf); + } + free((char *)sendBuf); + + return Success; +} + +int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + __GLXcontext *ctx; + xGLXQueryContextInfoEXTReq *req; + xGLXQueryContextInfoEXTReply reply; + int nProps; + int *sendBuf, *pSendBuf; + int nReplyBytes; + + req = (xGLXQueryContextInfoEXTReq *)pc; + dixLookupResourceByType((pointer*) &ctx, + req->context, __glXContextRes, + client, DixReadAccess); + + if (!ctx) { + client->errorValue = req->context; + return __glXBadContext; + } + + nProps = 4; + + reply.length = nProps << 1; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.n = nProps; + + nReplyBytes = reply.length << 2; + sendBuf = (int *)malloc(nReplyBytes); + pSendBuf = sendBuf; + *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; + *pSendBuf++ = (int)(ctx->share_id); + *pSendBuf++ = GLX_VISUAL_ID_EXT; + *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0); + *pSendBuf++ = GLX_SCREEN_EXT; + *pSendBuf++ = (int)(ctx->pScreen->myNum); + *pSendBuf++ = GLX_FBCONFIG_ID; + *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0); + + if (client->swapped) { + __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); + } else { + WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); + WriteToClient(client, nReplyBytes, (char *)sendBuf); + } + free((char *)sendBuf); + + return Success; +} + +int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc; + xGLXCreatePbufferReq *be_req; + int screen = req->screen; + GLXFBConfigID fbconfigId = req->fbconfig; + GLXPbuffer pbuffer = req->pbuffer; + __glXPbuffer *pGlxPbuffer; + int numAttribs = req->numAttribs; + int *attr; + ScreenPtr pScreen; + __GLXFBConfig *pGlxFBConfig; + __GLXFBConfig *be_pGlxFBConfig; + XID be_xid; + Display *dpy; + DMXScreenInfo *dmxScreen; + int s; + int from_screen, to_screen; + + /* + ** Look up screen and FBConfig. + */ + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + pScreen = screenInfo.screens[screen]; + + /* + ** Find the FBConfigRec for this fbconfigid. + */ + if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { + client->errorValue = fbconfigId; + return __glXBadFBConfig; + } + + /* + ** Create the GLX part of the Pbuffer. + */ + pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer)); + if (!pGlxPbuffer) { + return BadAlloc; + } + + pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens ); + if (!pGlxPbuffer->be_xids) { + free(pGlxPbuffer); + return BadAlloc; + } + + /* + * Allocate an XID on the back-end server(s) and send him the request + */ + from_screen = to_screen = screen; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + dpy = GetBackEndDisplay(cl,s); + be_xid = XAllocID(dpy); + dmxScreen = &dmxScreens[s]; + be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s ); + + attr = (int *)( req+1 ); + + LockDisplay(dpy); + GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCreatePbuffer; + be_req->screen = be_pGlxFBConfig->screen; + be_req->fbconfig = be_pGlxFBConfig->id; + be_req->pbuffer = be_xid; + be_req->numAttribs = numAttribs; + + /* Send attributes */ + if ( attr != NULL ) { + CARD32 *pc = (CARD32 *)(be_req + 1); + + while (numAttribs-- > 0) { + *pc++ = *attr++; /* token */ + *pc++ = *attr++; /* value */ + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + pGlxPbuffer->be_xids[s] = be_xid; + } + + + pGlxPbuffer->idExists = True; + pGlxPbuffer->refcnt = 0; + pGlxPbuffer->pFBConfig = pGlxFBConfig; + pGlxPbuffer->pScreen = pScreen; + + /* + ** Register the resource. + */ + if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) { + return BadAlloc; + } + + return Success; + +} + +int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; + xGLXDestroyPbufferReq *be_req; + GLXPbuffer pbuffer = req->pbuffer; + Display *dpy; + int screen; + DMXScreenInfo *dmxScreen; + __glXPbuffer *pGlxPbuffer; + int s; + int from_screen, to_screen; + + /* + ** Check if it's a valid Pbuffer + */ + dixLookupResourceByType((pointer*) &pGlxPbuffer, pbuffer, + __glXPbufferRes, NullClient, DixUnknownAccess); + if (!pGlxPbuffer) { + client->errorValue = pbuffer; + return __glXBadPbuffer; + } + + screen = pGlxPbuffer->pScreen->myNum; + + from_screen = to_screen = screen; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + dpy = GetBackEndDisplay(cl,s); + dmxScreen = &dmxScreens[s]; + + /* send the destroy request to the back-end server */ + LockDisplay(dpy); + GetReq(GLXDestroyPbuffer, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXDestroyPbuffer; + be_req->pbuffer = pGlxPbuffer->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + + FreeResource(pbuffer, RT_NONE); + + return Success; +} + +int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; + xGLXGetDrawableAttributesReq *be_req; + xGLXGetDrawableAttributesReply reply; + ClientPtr client = cl->client; + GLXDrawable drawId = req->drawable; + GLXDrawable be_drawable = 0; + DrawablePtr pDraw = NULL; + Display *dpy; + int screen, rc; + DMXScreenInfo *dmxScreen; + CARD32 *attribs = NULL; + int attribs_size = 0; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; +#endif + + if (drawId != None) { + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); + if (rc == Success && pDraw->type == DRAWABLE_WINDOW) { + WindowPtr pWin = (WindowPtr)pDraw; + be_drawable = 0; + screen = pWin->drawable.pScreen->myNum; + } else { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (!pDraw) { + __GLXpixmap *pGlxPixmap; + dixLookupResourceByType((pointer*) &pGlxPixmap, + drawId, __glXPixmapRes, + NullClient, DixUnknownAccess); + if (pGlxPixmap) { + pDraw = pGlxPixmap->pDraw; + screen = pGlxPixmap->pScreen->myNum; + be_drawable = pGlxPixmap->be_xids[screen]; + } + } + + if (!pDraw) { + __glXWindow *pGlxWindow; + dixLookupResourceByType((pointer*) &pGlxWindow, + drawId, __glXWindowRes, + NullClient, DixUnknownAccess); + if (pGlxWindow) { + pDraw = pGlxWindow->pDraw; + screen = pGlxWindow->pScreen->myNum; + be_drawable = 0; + } + } + + if (!pDraw) { + __glXPbuffer *pGlxPbuffer; + dixLookupResourceByType((pointer*) &pGlxPbuffer, + drawId, __glXPbufferRes, + NullClient, DixUnknownAccess); + if (pGlxPbuffer) { + pDraw = (DrawablePtr)pGlxPbuffer; + screen = pGlxPbuffer->pScreen->myNum; + be_drawable = pGlxPbuffer->be_xids[screen]; + } + } + } + + if (!pDraw) { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + /* if the drawable is a window or GLXWindow - + * we need to find the base id on the back-end server + */ + if (!be_drawable) { + WindowPtr pWin = (WindowPtr)pDraw; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess)) { + client->errorValue = drawId; + return __glXBadDrawable; + } + + dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, + DixReadAccess); + } +#endif + + if (pWin) { + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_drawable) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + else { + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + + /* send the request to the back-end server */ + dpy = GetBackEndDisplay(cl,screen); + dmxScreen = &dmxScreens[screen]; + + /* make sure drawable exists on back-end */ + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXGetDrawableAttributes, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXGetDrawableAttributes; + be_req->drawable = be_drawable; + be_req->length = req->length; + if (!_XReply(dpy, (xReply *) &reply, 0, False)) { + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + if (reply.numAttribs) { + attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32; + attribs = (CARD32 *) malloc(attribs_size); + if (attribs == NULL) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + + _XRead(dpy, (char *) attribs, attribs_size); + } + + UnlockDisplay(dpy); + SyncHandle(); + + + /* send the reply back to the client */ + reply.sequenceNumber = client->sequence; + if (client->swapped) { + __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs); + } + else { + WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply); + WriteToClient(client, attribs_size, (char *)attribs); + } + + free(attribs); + + return Success; +} + +int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc; + xGLXChangeDrawableAttributesReq *be_req; + ClientPtr client = cl->client; + GLXDrawable drawId = req->drawable; + GLXDrawable be_drawable = 0; + DrawablePtr pDraw = NULL; + Display *dpy; + int screen, rc; + DMXScreenInfo *dmxScreen; + + if (drawId != None) { + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess); + if (rc == Success && pDraw->type == DRAWABLE_WINDOW) { + be_drawable = 0; + screen = pDraw->pScreen->myNum; + } else { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (!pDraw) { + __GLXpixmap *pGlxPixmap; + dixLookupResourceByType((pointer*) &pGlxPixmap, + drawId, __glXPixmapRes, + NullClient, DixUnknownAccess); + if (pGlxPixmap) { + pDraw = pGlxPixmap->pDraw; + screen = pGlxPixmap->pScreen->myNum; + be_drawable = pGlxPixmap->be_xids[screen]; + } + } + + if (!pDraw) { + __glXWindow *pGlxWindow; + dixLookupResourceByType((pointer*) &pGlxWindow, + drawId, __glXWindowRes, + NullClient, DixUnknownAccess); + if (pGlxWindow) { + pDraw = pGlxWindow->pDraw; + screen = pGlxWindow->pScreen->myNum; + be_drawable = 0; + } + } + + if (!pDraw) { + __glXPbuffer *pGlxPbuffer; + dixLookupResourceByType((pointer*) &pGlxPbuffer, + drawId, __glXPbufferRes, + NullClient, DixUnknownAccess); + if (pGlxPbuffer) { + pDraw = (DrawablePtr)pGlxPbuffer; + screen = pGlxPbuffer->pScreen->myNum; + be_drawable = pGlxPbuffer->be_xids[screen]; + } + } + } + + if (!pDraw) { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + /* if the drawable is a window or GLXWindow - + * we need to find the base id on the back-end server + */ + if (!be_drawable) { + WindowPtr pWin = (WindowPtr)pDraw; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + PanoramiXRes *pXinDraw; + if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess)) { + client->errorValue = drawId; + return __glXBadDrawable; + } + + dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, + DixReadAccess); + } +#endif + + if (pWin) { + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_drawable) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + else { + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + + /* send the request to the back-end server */ + dpy = GetBackEndDisplay(cl,screen); + dmxScreen = &dmxScreens[screen]; + + /* make sure drawable exists on back-end */ + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReqExtra(GLXChangeDrawableAttributes, + 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXChangeDrawableAttributes; + be_req->drawable = be_drawable; + be_req->numAttribs = req->numAttribs; + be_req->length = req->length; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag) +{ + ClientPtr client = cl->client; + xGLXRenderLargeReq *req; + GLint maxSize, amount; + GLint totalRequests, requestNumber; + GLint dataLen; + GLbyte *data; + __GLXcontext *glxc; + int s; + int from_screen, to_screen; + + maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq); + dataLen = cl->largeCmdBytesTotal; + totalRequests = (dataLen / maxSize); + if (dataLen % maxSize) totalRequests++; + + glxc = __glXLookupContextByTag(cl, contextTag); + if (!glxc) { + client->errorValue = contextTag; + return __glXBadContext; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + /* + ** Send enough requests until the whole array is sent. + */ + requestNumber = 1; + data = cl->largeCmdBuf; + while (dataLen > 0) { + amount = dataLen; + if (amount > maxSize) { + amount = maxSize; + } + + for (s=from_screen; s<=to_screen; s++) { + + Display *dpy = GetBackEndDisplay(cl,s); + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + + LockDisplay(dpy); + GetReq(GLXRenderLarge,req); + req->reqType = dmxScreen->glxMajorOpcode; + req->glxCode = X_GLXRenderLarge; + req->contextTag = GetCurrentBackEndTag(cl,contextTag,s); + req->length += (amount + 3) >> 2; + req->requestNumber = requestNumber++; + req->requestTotal = totalRequests; + req->dataBytes = amount; + Data(dpy, ((const char*)data), amount); + dataLen -= amount; + data = ((GLbyte *) data) + amount; + UnlockDisplay(dpy); + SyncHandle(); + } + } + + return Success; +} diff --git a/xorg-server/hw/dmx/glxProxy/glxsingle.c b/xorg-server/hw/dmx/glxProxy/glxsingle.c index 7856f5884..33cc612a7 100644 --- a/xorg-server/hw/dmx/glxProxy/glxsingle.c +++ b/xorg-server/hw/dmx/glxProxy/glxsingle.c @@ -1,1015 +1,1016 @@ -/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 - * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifdef HAVE_DMX_CONFIG_H -#include -#endif - -#include "dmx.h" -#include "dmxwindow.h" -#include "dmxpixmap.h" -#include "dmxfont.h" -#include "dmxcb.h" - -#include "glxserver.h" -#include "glxext.h" -#include "g_disptab.h" -/* #include "g_disptab_EXT.h" */ -#include "unpack.h" -#include "glxutil.h" - -#include "GL/glxproto.h" - -#ifdef PANORAMIX -#include "panoramiXsrv.h" -#endif - -/* - * GetReqSingle - this is the equivalent of GetReq macro - * from Xlibint.h but it does not set the reqType field (the opcode). - * this is because the GL single opcodes has different naming convension - * the other X opcodes (ie. X_GLsop_GetFloatv). - */ -#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) -#define GetReqSingle(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ - req->length = (SIZEOF(x##name##Req))>>2;\ - dpy->bufptr += SIZEOF(x##name##Req);\ - dpy->request++ - -#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ -#define GetReqSingle(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ - req->length = (SIZEOF(x/**/name/**/Req))>>2;\ - dpy->bufptr += SIZEOF(x/**/name/**/Req);\ - dpy->request++ -#endif - -#define X_GLXSingle 0 /* needed by GetReqExtra */ - -extern Display *GetBackEndDisplay( __GLXclientState *cl, int s ); -extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s); - -static int swap_vec_element_size = 0; - -static void SendSwappedReply( ClientPtr client, - xGLXSingleReply *reply, - char *buf, - int buf_size ) -{ - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply->sequenceNumber); - __GLX_SWAP_INT(&reply->length); - __GLX_SWAP_INT(&reply->retval); - __GLX_SWAP_INT(&reply->size); - - if ( (buf_size == 0) && (swap_vec_element_size > 0) ) { - /* - * the reply has single component - need to swap pad3 - */ - if (swap_vec_element_size == 2) { - __GLX_SWAP_SHORT(&reply->pad3); - } - else if (swap_vec_element_size == 4) { - __GLX_SWAP_INT(&reply->pad3); - __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4 - * i.e GetConvolutionFilter - */ - } - else if (swap_vec_element_size == 8) { - __GLX_SWAP_DOUBLE(&reply->pad3); - } - } - else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) { - /* - * the reply has vector of elements which needs to be swapped - */ - int vsize = buf_size / swap_vec_element_size; - char *p = buf; - int i; - - for (i=0; ipad3); - __GLX_SWAP_INT(&reply->pad4); - __GLX_SWAP_INT(&reply->pad5); - __GLX_SWAP_INT(&reply->pad6); - - } - - WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply); - if (buf_size > 0) - WriteToClient(client, buf_size, (char *)buf); - -} - -int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - xGLXSingleReq *be_req; - __GLXcontext *glxc; - int from_screen = 0; - int to_screen = 0; - int buf_size; - int s; - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return 0; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - pc += sz_xGLXSingleReq; - buf_size = (req->length << 2) - sz_xGLXSingleReq; - - /* - * just forward the request to back-end server(s) - */ - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReqSingle(GLXSingle,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = req->glxCode; - be_req->length = req->length; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); - if (buf_size > 0) - _XSend(dpy, (const char *)pc, buf_size); - UnlockDisplay(dpy); - SyncHandle(); - - if (req->glxCode == X_GLsop_Flush) { - XFlush(dpy); - } - - } - - return Success; -} - -int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc ) -{ - ClientPtr client = cl->client; - xGLXSingleReq *req = (xGLXSingleReq *)pc; - xGLXSingleReq *be_req; - xGLXSingleReply reply; - xGLXSingleReply be_reply; - __GLXcontext *glxc; - int buf_size; - char *be_buf; - int be_buf_size; - DMXScreenInfo *dmxScreen; - Display *dpy; - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return __glXBadContext; - } - - pc += sz_xGLXSingleReq; - buf_size = (req->length << 2) - sz_xGLXSingleReq; - - dmxScreen = &dmxScreens[glxc->pScreen->myNum]; - dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum); - - /* - * send the request to the first back-end server - */ - LockDisplay(dpy); - GetReqSingle(GLXSingle,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = req->glxCode; - be_req->length = req->length; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum); - if (buf_size > 0) - _XSend(dpy, (const char *)pc, buf_size); - - /* - * get the reply from the back-end server - */ - _XReply(dpy, (xReply*) &be_reply, 0, False); - be_buf_size = be_reply.length << 2; - if (be_buf_size > 0) { - be_buf = (char *)malloc( be_buf_size ); - if (be_buf) { - _XRead(dpy, be_buf, be_buf_size); - } - else { - /* Throw data on the floor */ - _XEatData(dpy, be_buf_size); - return BadAlloc; - } - } - - UnlockDisplay(dpy); - SyncHandle(); - - /* - * send the reply to the client - */ - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = be_reply.length; - reply.retval = be_reply.retval; - reply.size = be_reply.size; - reply.pad3 = be_reply.pad3; - reply.pad4 = be_reply.pad4; - - if (client->swapped) { - SendSwappedReply( client, &reply, be_buf, be_buf_size ); - } - else { - WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); - if (be_buf_size > 0) - WriteToClient(client, be_buf_size, (char *)be_buf); - } - - if (be_buf_size > 0) free(be_buf); - - return Success; -} - -int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc ) -{ - ClientPtr client = cl->client; - xGLXSingleReq *req = (xGLXSingleReq *)pc; - xGLXSingleReq *be_req; - xGLXSingleReply reply; - xGLXSingleReply be_reply; - __GLXcontext *glxc; - int buf_size; - char *be_buf; - int be_buf_size; - int from_screen = 0; - int to_screen = 0; - int s; - - DMXScreenInfo *dmxScreen; - Display *dpy; - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return 0; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - pc += sz_xGLXSingleReq; - buf_size = (req->length << 2) - sz_xGLXSingleReq; - - /* - * send the request to the first back-end server(s) - */ - for (s=to_screen; s>=from_screen; s--) { - dmxScreen = &dmxScreens[s]; - dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReqSingle(GLXSingle,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = req->glxCode; - be_req->length = req->length; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); - if (buf_size > 0) - _XSend(dpy, (const char *)pc, buf_size); - - /* - * get the reply from the back-end server - */ - _XReply(dpy, (xReply*) &be_reply, 0, False); - be_buf_size = be_reply.length << 2; - if (be_buf_size > 0) { - be_buf = (char *)malloc( be_buf_size ); - if (be_buf) { - _XRead(dpy, be_buf, be_buf_size); - } - else { - /* Throw data on the floor */ - _XEatData(dpy, be_buf_size); - return BadAlloc; - } - } - - UnlockDisplay(dpy); - SyncHandle(); - - if (s > from_screen && be_buf_size > 0) { - free(be_buf); - } - } - - /* - * send the reply to the client - */ - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = be_reply.length; - reply.retval = be_reply.retval; - reply.size = be_reply.size; - reply.pad3 = be_reply.pad3; - reply.pad4 = be_reply.pad4; - - if (client->swapped) { - SendSwappedReply( client, &reply, be_buf, be_buf_size ); - } - else { - WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); - if (be_buf_size > 0) - WriteToClient(client, be_buf_size, (char *)be_buf); - } - - if (be_buf_size > 0) free(be_buf); - - return Success; -} - -int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 0; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXForwardSingleReq( cl, pc ) ); -} - -int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 0; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXForwardPipe0WithReply( cl, pc ) ); -} - -int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 2; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - - return( __glXForwardPipe0WithReply( cl, pc ) ); -} - -int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 4; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - - return( __glXForwardPipe0WithReply( cl, pc ) ); -} - -int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 8; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - - return( __glXForwardPipe0WithReply( cl, pc ) ); -} - -int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 0; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - - return( __glXForwardAllWithReply( cl, pc ) ); -} - -int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 2; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - - return( __glXForwardAllWithReply( cl, pc ) ); -} - -int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 4; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - - return( __glXForwardAllWithReply( cl, pc ) ); -} - -int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 8; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXSingleReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXSingleReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - - return( __glXForwardAllWithReply( cl, pc ) ); -} - -static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h, - int *elementbits_return, int *rowbytes_return ) -{ - GLint elements, esize; - GLint rowsize, padding; - - if (w < 0 || h < 0) { - return -1; - } - switch (format) { - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - default: - return -1; - } - /* - ** According to the GLX protocol, each row must be padded to a multiple of - ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel - ** store modes of the GL. - */ - switch (type) { - case GL_BITMAP: - if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { - rowsize = ((w * elements)+7)/8; - padding = rowsize % 4; - if (padding) { - rowsize += 4 - padding; - } - if (elementbits_return) *elementbits_return = elements; - if (rowbytes_return) *rowbytes_return = rowsize; - return rowsize * h; - } else { - return -1; - } - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return -1; - } - rowsize = w * elements * esize; - padding = rowsize % 4; - if (padding) { - rowsize += 4 - padding; - } - - if (elementbits_return) *elementbits_return = esize*elements*8; - if (rowbytes_return) *rowbytes_return = rowsize; - - return rowsize * h; -} - -static int intersectRect( int x1, int x2, int y1, int y2, - int X1, int X2, int Y1, int Y2, - int *ix1, int *ix2, int *iy1, int *iy2 ) -{ - int right = (x2 < X2 ? x2 : X2); - int bottom = (y2 < Y2 ? y2 : Y2); - int left = (x1 > X1 ? x1 : X1); - int top = (y1 > Y1 ? y1 : Y1); - int width = right - left + 1; - int height = bottom - top + 1; - - if ( (width <= 0) || (height <= 0) ) { - *ix1 = *ix2 = *iy1 = *iy2 = 0; - return 0; - } - else { - *ix1 = left; - *ix2 = right; - *iy1 = top; - *iy2 = bottom; - return width * height; - } - -} - -int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc) -{ - xGLXSingleReq *req = (xGLXSingleReq *)pc; - xGLXSingleReq *be_req; - xGLXReadPixelsReply reply; - xGLXReadPixelsReply be_reply; - GLbyte *be_pc; - GLint x,y; - GLsizei width, height; - GLenum format, type; - GLboolean swapBytes, lsbFirst; - ClientPtr client = cl->client; - DrawablePtr pDraw; - __GLXcontext *glxc; - int from_screen = 0; - int to_screen = 0; - char *buf; - int buf_size; - int s; - int win_x1, win_x2; - int win_y1, win_y2; - int ebits, rowsize; - __GLX_DECLARE_SWAP_VARIABLES; - - if (client->swapped) { - __GLX_SWAP_INT(&req->contextTag); - } - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return 0; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - pc += sz_xGLXSingleReq; - x = *(GLint *)(pc + 0); - y = *(GLint *)(pc + 4); - width = *(GLsizei *)(pc + 8); - height = *(GLsizei *)(pc + 12); - format = *(GLenum *)(pc + 16); - type = *(GLenum *)(pc + 20); - swapBytes = *(GLboolean *)(pc + 24); - lsbFirst = *(GLboolean *)(pc + 25); - - if (client->swapped) { - __GLX_SWAP_INT(&x); - __GLX_SWAP_INT(&y); - __GLX_SWAP_INT(&width); - __GLX_SWAP_INT(&height); - __GLX_SWAP_INT(&format); - __GLX_SWAP_INT(&type); - swapBytes = !swapBytes; - } - - buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize); - if (buf_size > 0) { - buf = (char *) malloc( buf_size ); - if ( !buf ) { - return BadAlloc; - } - } - else { - buf_size = 0; - } - - if (buf_size > 0) { - /* - * Get the current drawable this context is bound to - */ - pDraw = __glXLookupDrawableByTag( cl, req->contextTag ); - win_x1 = pDraw->x + x; - win_x2 = win_x1 + width - 1; - win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y; - win_y2 = win_y1 + height - 1; - if (pDraw->type != DRAWABLE_WINDOW) { - from_screen = to_screen = 0; - } - - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - int scr_x1 = dmxScreen->rootXOrigin; - int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1; - int scr_y1 = dmxScreen->rootYOrigin; - int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1; - int wx1, wx2, wy1, wy2; - int sx, sy, sw, sh; - int npixels; - - /* - * find the window portion that is on the current screen - */ - if (pDraw->type == DRAWABLE_WINDOW) { - npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2, - win_x1, win_x2, win_y1, win_y2, - &wx1, &wx2, &wy1, &wy2 ); - } - else { - wx1 = win_x1; - wx2 = win_x2; - wy1 = win_y1; - wy2 = win_y2; - npixels = (wx2-wx1+1) * (wy2-wy1+1); - } - - if (npixels > 0) { - - /* send the request to the back-end server */ - LockDisplay(dpy); - GetReqExtra(GLXSingle,__GLX_PAD(26),be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = X_GLsop_ReadPixels; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); - be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq); - - sx = wx1 - pDraw->x; - sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height); - sw = (wx2-wx1+1); - sh = (wy2-wy1+1); - - *(GLint *)(be_pc + 0) = sx; /* x */ - *(GLint *)(be_pc + 4) = sy; /* y */ - *(GLsizei *)(be_pc + 8) = sw; /* width */ - *(GLsizei *)(be_pc + 12) = sh; /* height */ - *(GLenum *)(be_pc + 16) = format; - *(GLenum *)(be_pc + 20) = type; - *(GLboolean *)(be_pc + 24) = swapBytes; - *(GLboolean *)(be_pc + 25) = lsbFirst; - - _XReply(dpy, (xReply*) &be_reply, 0, False); - - if (be_reply.length > 0) { - char *be_buf; - int be_buf_size = be_reply.length << 2; - - be_buf = (char *) malloc( be_buf_size ); - if (be_buf) { - _XRead(dpy, be_buf, be_buf_size); - - /* copy pixels data to the right location of the */ - /* reply buffer */ - if ( type != GL_BITMAP ) { - int pbytes = ebits / 8; - char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes; - char *src = be_buf; - int pad = (pbytes * sw) % 4; - int r; - - for (r=0; r> (sx % 8); - unsigned char src_mask = 0x80; - char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8; - char *src = be_buf + r*src_rowsize; - int b; - - for (b=0; b 1) dst_mask >>= 1; - else { - dst_mask = 0x80; - dst++; - } - - if (src_mask > 1) src_mask >>= 1; - else { - src_mask = 0x80; - src++; - } - } - } - - } - - free( be_buf ); - } - else { - /* Throw data on the floor */ - _XEatData(dpy, be_buf_size); - free( buf ); - return BadAlloc; - } - } - - UnlockDisplay(dpy); - SyncHandle(); - - } /* of npixels > 0 */ - - } /* of for loop */ - - } /* of if buf_size > 0 */ - - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = buf_size >> 2; - - if (client->swapped) { - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - } - - WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply); - if (buf_size > 0) { - WriteToClient(client, buf_size, (char *)buf); - free( buf ); - } - - return Success; -} - -int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc) -{ - __GLX_DECLARE_SWAP_VARIABLES; - GLbyte *lpc = pc; - - lpc += sz_xGLXSingleReq; - __GLX_SWAP_INT(lpc+0); - __GLX_SWAP_INT(lpc+4); - __GLX_SWAP_INT(lpc+8); - __GLX_SWAP_INT(lpc+12); - - /* reverse swapBytes */ - *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16); - - return( __glXForwardPipe0WithReplySwap( cl, pc ) ); -} - -int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc) -{ - __GLX_DECLARE_SWAP_VARIABLES; - GLbyte *lpc = pc; - - lpc += sz_xGLXSingleReq; - __GLX_SWAP_INT(lpc+0); - __GLX_SWAP_INT(lpc+4); - __GLX_SWAP_INT(lpc+8); - - /* reverse swapBytes */ - *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12); - - return( __glXForwardPipe0WithReplySwap( cl, pc ) ); -} - - +/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DMX_CONFIG_H +#include +#endif + +#include "dmx.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" +#include "dmxfont.h" +#include "dmxcb.h" + +#include "glxserver.h" +#include "glxext.h" +#include "g_disptab.h" +/* #include "g_disptab_EXT.h" */ +#include "unpack.h" +#include "glxutil.h" + +#include "GL/glxproto.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +/* + * GetReqSingle - this is the equivalent of GetReq macro + * from Xlibint.h but it does not set the reqType field (the opcode). + * this is because the GL single opcodes has different naming convension + * the other X opcodes (ie. X_GLsop_GetFloatv). + */ +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define GetReqSingle(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x##name##Req))>>2;\ + dpy->bufptr += SIZEOF(x##name##Req);\ + dpy->request++ + +#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ +#define GetReqSingle(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x/**/name/**/Req))>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req);\ + dpy->request++ +#endif + +#define X_GLXSingle 0 /* needed by GetReqExtra */ + +extern Display *GetBackEndDisplay( __GLXclientState *cl, int s ); +extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s); + +static int swap_vec_element_size = 0; + +static void SendSwappedReply( ClientPtr client, + xGLXSingleReply *reply, + char *buf, + int buf_size ) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->retval); + __GLX_SWAP_INT(&reply->size); + + if ( (buf_size == 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has single component - need to swap pad3 + */ + if (swap_vec_element_size == 2) { + __GLX_SWAP_SHORT(&reply->pad3); + } + else if (swap_vec_element_size == 4) { + __GLX_SWAP_INT(&reply->pad3); + __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4 + * i.e GetConvolutionFilter + */ + } + else if (swap_vec_element_size == 8) { + __GLX_SWAP_DOUBLE(&reply->pad3); + } + } + else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has vector of elements which needs to be swapped + */ + int vsize = buf_size / swap_vec_element_size; + char *p = buf; + int i; + + for (i=0; ipad3); + __GLX_SWAP_INT(&reply->pad4); + __GLX_SWAP_INT(&reply->pad5); + __GLX_SWAP_INT(&reply->pad6); + + } + + WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply); + if (buf_size > 0) + WriteToClient(client, buf_size, (char *)buf); + +} + +int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int buf_size; + int s; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXSingleReq; + buf_size = (req->length << 2) - sz_xGLXSingleReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqSingle(GLXSingle,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + UnlockDisplay(dpy); + SyncHandle(); + + if (req->glxCode == X_GLsop_Flush) { + XFlush(dpy); + } + + } + + return Success; +} + +int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + xGLXSingleReply reply; + xGLXSingleReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size; + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return __glXBadContext; + } + + pc += sz_xGLXSingleReq; + buf_size = (req->length << 2) - sz_xGLXSingleReq; + + dmxScreen = &dmxScreens[glxc->pScreen->myNum]; + dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum); + + /* + * send the request to the first back-end server + */ + LockDisplay(dpy); + GetReqSingle(GLXSingle,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + /* + * send the reply to the client + */ + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = be_reply.length; + reply.retval = be_reply.retval; + reply.size = be_reply.size; + reply.pad3 = be_reply.pad3; + reply.pad4 = be_reply.pad4; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + xGLXSingleReply reply; + xGLXSingleReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size = 0; + int from_screen = 0; + int to_screen = 0; + int s; + + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXSingleReq; + buf_size = (req->length << 2) - sz_xGLXSingleReq; + + /* + * send the request to the first back-end server(s) + */ + for (s=to_screen; s>=from_screen; s--) { + dmxScreen = &dmxScreens[s]; + dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqSingle(GLXSingle,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + if (s > from_screen && be_buf_size > 0) { + free(be_buf); + } + } + + /* + * send the reply to the client + */ + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = be_reply.length; + reply.retval = be_reply.retval; + reply.size = be_reply.size; + reply.pad3 = be_reply.pad3; + reply.pad4 = be_reply.pad4; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXForwardSingleReq( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h, + int *elementbits_return, int *rowbytes_return ) +{ + GLint elements, esize; + GLint rowsize, padding; + + if (w < 0 || h < 0) { + return -1; + } + switch (format) { + case GL_COLOR_INDEX: + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + elements = 1; + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + elements = 1; + break; + case GL_LUMINANCE_ALPHA: + elements = 2; + break; + case GL_RGB: + case GL_BGR: + elements = 3; + break; + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + elements = 4; + break; + default: + return -1; + } + /* + ** According to the GLX protocol, each row must be padded to a multiple of + ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel + ** store modes of the GL. + */ + switch (type) { + case GL_BITMAP: + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { + rowsize = ((w * elements)+7)/8; + padding = rowsize % 4; + if (padding) { + rowsize += 4 - padding; + } + if (elementbits_return) *elementbits_return = elements; + if (rowbytes_return) *rowbytes_return = rowsize; + return rowsize * h; + } else { + return -1; + } + case GL_BYTE: + case GL_UNSIGNED_BYTE: + esize = 1; + break; + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + esize = 1; + elements = 1; + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + esize = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + esize = 2; + elements = 1; + break; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + esize = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + esize = 4; + elements = 1; + break; + default: + return -1; + } + rowsize = w * elements * esize; + padding = rowsize % 4; + if (padding) { + rowsize += 4 - padding; + } + + if (elementbits_return) *elementbits_return = esize*elements*8; + if (rowbytes_return) *rowbytes_return = rowsize; + + return rowsize * h; +} + +static int intersectRect( int x1, int x2, int y1, int y2, + int X1, int X2, int Y1, int Y2, + int *ix1, int *ix2, int *iy1, int *iy2 ) +{ + int right = (x2 < X2 ? x2 : X2); + int bottom = (y2 < Y2 ? y2 : Y2); + int left = (x1 > X1 ? x1 : X1); + int top = (y1 > Y1 ? y1 : Y1); + int width = right - left + 1; + int height = bottom - top + 1; + + if ( (width <= 0) || (height <= 0) ) { + *ix1 = *ix2 = *iy1 = *iy2 = 0; + return 0; + } + else { + *ix1 = left; + *ix2 = right; + *iy1 = top; + *iy2 = bottom; + return width * height; + } + +} + +int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + xGLXReadPixelsReply reply; + xGLXReadPixelsReply be_reply; + GLbyte *be_pc; + GLint x,y; + GLsizei width, height; + GLenum format, type; + GLboolean swapBytes, lsbFirst; + ClientPtr client = cl->client; + DrawablePtr pDraw; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + char *buf; + int buf_size; + int s; + int win_x1, win_x2; + int win_y1, win_y2; + int ebits, rowsize; + __GLX_DECLARE_SWAP_VARIABLES; + + if (client->swapped) { + __GLX_SWAP_INT(&req->contextTag); + } + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXSingleReq; + x = *(GLint *)(pc + 0); + y = *(GLint *)(pc + 4); + width = *(GLsizei *)(pc + 8); + height = *(GLsizei *)(pc + 12); + format = *(GLenum *)(pc + 16); + type = *(GLenum *)(pc + 20); + swapBytes = *(GLboolean *)(pc + 24); + lsbFirst = *(GLboolean *)(pc + 25); + + if (client->swapped) { + __GLX_SWAP_INT(&x); + __GLX_SWAP_INT(&y); + __GLX_SWAP_INT(&width); + __GLX_SWAP_INT(&height); + __GLX_SWAP_INT(&format); + __GLX_SWAP_INT(&type); + swapBytes = !swapBytes; + } + + buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize); + if (buf_size > 0) { + buf = (char *) malloc( buf_size ); + if ( !buf ) { + return BadAlloc; + } + } + else { + buf_size = 0; + buf = NULL; + } + + if (buf_size > 0) { + /* + * Get the current drawable this context is bound to + */ + pDraw = __glXLookupDrawableByTag( cl, req->contextTag ); + win_x1 = pDraw->x + x; + win_x2 = win_x1 + width - 1; + win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y; + win_y2 = win_y1 + height - 1; + if (pDraw->type != DRAWABLE_WINDOW) { + from_screen = to_screen = 0; + } + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + int scr_x1 = dmxScreen->rootXOrigin; + int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1; + int scr_y1 = dmxScreen->rootYOrigin; + int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1; + int wx1, wx2, wy1, wy2; + int sx, sy, sw, sh; + int npixels; + + /* + * find the window portion that is on the current screen + */ + if (pDraw->type == DRAWABLE_WINDOW) { + npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2, + win_x1, win_x2, win_y1, win_y2, + &wx1, &wx2, &wy1, &wy2 ); + } + else { + wx1 = win_x1; + wx2 = win_x2; + wy1 = win_y1; + wy2 = win_y2; + npixels = (wx2-wx1+1) * (wy2-wy1+1); + } + + if (npixels > 0) { + + /* send the request to the back-end server */ + LockDisplay(dpy); + GetReqExtra(GLXSingle,__GLX_PAD(26),be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLsop_ReadPixels; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq); + + sx = wx1 - pDraw->x; + sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height); + sw = (wx2-wx1+1); + sh = (wy2-wy1+1); + + *(GLint *)(be_pc + 0) = sx; /* x */ + *(GLint *)(be_pc + 4) = sy; /* y */ + *(GLsizei *)(be_pc + 8) = sw; /* width */ + *(GLsizei *)(be_pc + 12) = sh; /* height */ + *(GLenum *)(be_pc + 16) = format; + *(GLenum *)(be_pc + 20) = type; + *(GLboolean *)(be_pc + 24) = swapBytes; + *(GLboolean *)(be_pc + 25) = lsbFirst; + + _XReply(dpy, (xReply*) &be_reply, 0, False); + + if (be_reply.length > 0) { + char *be_buf; + int be_buf_size = be_reply.length << 2; + + be_buf = (char *) malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + + /* copy pixels data to the right location of the */ + /* reply buffer */ + if ( type != GL_BITMAP ) { + int pbytes = ebits / 8; + char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes; + char *src = be_buf; + int pad = (pbytes * sw) % 4; + int r; + + for (r=0; r> (sx % 8); + unsigned char src_mask = 0x80; + char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8; + char *src = be_buf + r*src_rowsize; + int b; + + for (b=0; b 1) dst_mask >>= 1; + else { + dst_mask = 0x80; + dst++; + } + + if (src_mask > 1) src_mask >>= 1; + else { + src_mask = 0x80; + src++; + } + } + } + + } + + free( be_buf ); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + free( buf ); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + } /* of npixels > 0 */ + + } /* of for loop */ + + } /* of if buf_size > 0 */ + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = buf_size >> 2; + + if (client->swapped) { + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + } + + WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply); + if (buf_size > 0) { + WriteToClient(client, buf_size, (char *)buf); + free( buf ); + } + + return Success; +} + +int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + GLbyte *lpc = pc; + + lpc += sz_xGLXSingleReq; + __GLX_SWAP_INT(lpc+0); + __GLX_SWAP_INT(lpc+4); + __GLX_SWAP_INT(lpc+8); + __GLX_SWAP_INT(lpc+12); + + /* reverse swapBytes */ + *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16); + + return( __glXForwardPipe0WithReplySwap( cl, pc ) ); +} + +int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + GLbyte *lpc = pc; + + lpc += sz_xGLXSingleReq; + __GLX_SWAP_INT(lpc+0); + __GLX_SWAP_INT(lpc+4); + __GLX_SWAP_INT(lpc+8); + + /* reverse swapBytes */ + *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12); + + return( __glXForwardPipe0WithReplySwap( cl, pc ) ); +} + + diff --git a/xorg-server/hw/dmx/glxProxy/glxvendor.c b/xorg-server/hw/dmx/glxProxy/glxvendor.c index 26a9c92fb..0b6ba4134 100644 --- a/xorg-server/hw/dmx/glxProxy/glxvendor.c +++ b/xorg-server/hw/dmx/glxProxy/glxvendor.c @@ -1,585 +1,585 @@ -/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 - * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifdef HAVE_DMX_CONFIG_H -#include -#endif - -#include "dmx.h" -#include "dmxwindow.h" -#include "dmxpixmap.h" -#include "dmxfont.h" - -#include "glxserver.h" -#include "glxext.h" -#include "g_disptab.h" -/* #include "g_disptab_EXT.h" */ -#include "unpack.h" -#include "glxutil.h" - -#include "GL/glxproto.h" - -#ifdef PANORAMIX -#include "panoramiXsrv.h" -#endif - -/* - * GetReqVendorPrivate - this is the equivalent of GetReq macro - * from Xlibint.h but it does not set the reqType field (the opcode). - * this is because the GL single opcodes has different naming convension - * the other X opcodes (ie. X_GLsop_GetFloatv). - */ -#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) -#define GetReqVendorPrivate(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ - req->length = (SIZEOF(x##name##Req))>>2;\ - dpy->bufptr += SIZEOF(x##name##Req);\ - dpy->request++ - -#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ -#define GetReqVendorPrivate(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ - req->length = (SIZEOF(x/**/name/**/Req))>>2;\ - dpy->bufptr += SIZEOF(x/**/name/**/Req);\ - dpy->request++ -#endif - -extern Display *GetBackEndDisplay( __GLXclientState *cl, int s ); -extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s); - -static int swap_vec_element_size = 0; - -static void SendSwappedReply( ClientPtr client, - xGLXVendorPrivReply *reply, - char *buf, - int buf_size ) -{ - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply->sequenceNumber); - __GLX_SWAP_INT(&reply->length); - __GLX_SWAP_INT(&reply->retval); - __GLX_SWAP_INT(&reply->size); - - if ( (buf_size == 0) && (swap_vec_element_size > 0) ) { - /* - * the reply has single component - need to swap pad3 - */ - if (swap_vec_element_size == 2) { - __GLX_SWAP_SHORT(&reply->pad3); - } - else if (swap_vec_element_size == 4) { - __GLX_SWAP_INT(&reply->pad3); - __GLX_SWAP_INT(&reply->pad4); - } - else if (swap_vec_element_size == 8) { - __GLX_SWAP_DOUBLE(&reply->pad3); - } - } - else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) { - /* - * the reply has vector of elements which needs to be swapped - */ - int vsize = buf_size / swap_vec_element_size; - char *p = buf; - int i; - - for (i=0; ipad3); - __GLX_SWAP_INT(&reply->pad4); - __GLX_SWAP_INT(&reply->pad5); - __GLX_SWAP_INT(&reply->pad6); - - } - - WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)reply); - if (buf_size > 0) - WriteToClient(client, buf_size, (char *)buf); - -} - -int __glXVForwardSingleReq( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - xGLXVendorPrivateReq *be_req; - __GLXcontext *glxc; - int from_screen = 0; - int to_screen = 0; - int buf_size; - int s; - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return 0; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - pc += sz_xGLXVendorPrivateReq; - buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; - - /* - * just forward the request to back-end server(s) - */ - for (s=from_screen; s<=to_screen; s++) { - DMXScreenInfo *dmxScreen = &dmxScreens[s]; - Display *dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReqVendorPrivate(GLXVendorPrivate,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = req->glxCode; - be_req->length = req->length; - be_req->vendorCode = req->vendorCode; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); - if (buf_size > 0) - _XSend(dpy, (const char *)pc, buf_size); - UnlockDisplay(dpy); - SyncHandle(); - } - - return Success; -} - -int __glXVForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc ) -{ - ClientPtr client = cl->client; - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - xGLXVendorPrivateReq *be_req; - xGLXVendorPrivReply reply; - xGLXVendorPrivReply be_reply; - __GLXcontext *glxc; - int buf_size; - char *be_buf; - int be_buf_size; - DMXScreenInfo *dmxScreen; - Display *dpy; - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return __glXBadContext; - } - - pc += sz_xGLXVendorPrivateReq; - buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; - - dmxScreen = &dmxScreens[glxc->pScreen->myNum]; - dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum); - - /* - * send the request to the first back-end server - */ - LockDisplay(dpy); - GetReqVendorPrivate(GLXVendorPrivate,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = req->glxCode; - be_req->length = req->length; - be_req->vendorCode = req->vendorCode; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag, glxc->pScreen->myNum); - if (buf_size > 0) - _XSend(dpy, (const char *)pc, buf_size); - - /* - * get the reply from the back-end server - */ - _XReply(dpy, (xReply*) &be_reply, 0, False); - be_buf_size = be_reply.length << 2; - if (be_buf_size > 0) { - be_buf = (char *)malloc( be_buf_size ); - if (be_buf) { - _XRead(dpy, be_buf, be_buf_size); - } - else { - /* Throw data on the floor */ - _XEatData(dpy, be_buf_size); - return BadAlloc; - } - } - - UnlockDisplay(dpy); - SyncHandle(); - - /* - * send the reply to the client - */ - memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply ); - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - SendSwappedReply( client, &reply, be_buf, be_buf_size ); - } - else { - WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply); - if (be_buf_size > 0) - WriteToClient(client, be_buf_size, (char *)be_buf); - } - - if (be_buf_size > 0) free(be_buf); - - return Success; -} - -int __glXVForwardAllWithReply( __GLXclientState *cl, GLbyte *pc ) -{ - ClientPtr client = cl->client; - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - xGLXVendorPrivateReq *be_req; - xGLXVendorPrivReply reply; - xGLXVendorPrivReply be_reply; - __GLXcontext *glxc; - int buf_size; - char *be_buf; - int be_buf_size; - int from_screen = 0; - int to_screen = 0; - int s; - - DMXScreenInfo *dmxScreen; - Display *dpy; - - glxc = __glXLookupContextByTag(cl, req->contextTag); - if (!glxc) { - return 0; - } - from_screen = to_screen = glxc->pScreen->myNum; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - from_screen = 0; - to_screen = screenInfo.numScreens - 1; - } -#endif - - pc += sz_xGLXVendorPrivateReq; - buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; - - /* - * send the request to the first back-end server(s) - */ - for (s=to_screen; s>=from_screen; s--) { - dmxScreen = &dmxScreens[s]; - dpy = GetBackEndDisplay(cl,s); - - LockDisplay(dpy); - GetReqVendorPrivate(GLXVendorPrivate,be_req); - be_req->reqType = dmxScreen->glxMajorOpcode; - be_req->glxCode = req->glxCode; - be_req->length = req->length; - be_req->vendorCode = req->vendorCode; - be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); - if (buf_size > 0) - _XSend(dpy, (const char *)pc, buf_size); - - /* - * get the reply from the back-end server - */ - _XReply(dpy, (xReply*) &be_reply, 0, False); - be_buf_size = be_reply.length << 2; - if (be_buf_size > 0) { - be_buf = (char *)malloc( be_buf_size ); - if (be_buf) { - _XRead(dpy, be_buf, be_buf_size); - } - else { - /* Throw data on the floor */ - _XEatData(dpy, be_buf_size); - return BadAlloc; - } - } - - UnlockDisplay(dpy); - SyncHandle(); - - if (s > from_screen && be_buf_size > 0) { - free(be_buf); - } - } - - /* - * send the reply to the client - */ - memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply ); - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - SendSwappedReply( client, &reply, be_buf, be_buf_size ); - } - else { - WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply); - if (be_buf_size > 0) - WriteToClient(client, be_buf_size, (char *)be_buf); - } - - if (be_buf_size > 0) free(be_buf); - - return Success; -} - -int __glXVForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 0; - - return( __glXVForwardSingleReq( cl, pc ) ); -} - -int __glXVForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 0; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardPipe0WithReply( cl, pc ) ); -} - -int __glXVForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 2; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardPipe0WithReply( cl, pc ) ); -} - -int __glXVForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 4; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardPipe0WithReply( cl, pc ) ); -} - -int __glXVForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 8; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardPipe0WithReply( cl, pc ) ); -} - -int __glXVForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 0; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardAllWithReply( cl, pc ) ); -} - -int __glXVForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 2; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardAllWithReply( cl, pc ) ); -} - -int __glXVForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 4; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardAllWithReply( cl, pc ) ); -} - -int __glXVForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->vendorCode); - __GLX_SWAP_INT(&req->contextTag); - - swap_vec_element_size = 8; - - /* - * swap extra data in request - assuming all data - * (if available) are arrays of 4 bytes components ! - */ - if (req->length > sz_xGLXVendorPrivateReq/4) { - int *data = (int *)(req+1); - int count = req->length - sz_xGLXVendorPrivateReq/4; - __GLX_SWAP_INT_ARRAY(data, count ); - } - - return( __glXVForwardAllWithReply( cl, pc ) ); -} - +/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DMX_CONFIG_H +#include +#endif + +#include "dmx.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" +#include "dmxfont.h" + +#include "glxserver.h" +#include "glxext.h" +#include "g_disptab.h" +/* #include "g_disptab_EXT.h" */ +#include "unpack.h" +#include "glxutil.h" + +#include "GL/glxproto.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +/* + * GetReqVendorPrivate - this is the equivalent of GetReq macro + * from Xlibint.h but it does not set the reqType field (the opcode). + * this is because the GL single opcodes has different naming convension + * the other X opcodes (ie. X_GLsop_GetFloatv). + */ +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define GetReqVendorPrivate(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x##name##Req))>>2;\ + dpy->bufptr += SIZEOF(x##name##Req);\ + dpy->request++ + +#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ +#define GetReqVendorPrivate(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x/**/name/**/Req))>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req);\ + dpy->request++ +#endif + +extern Display *GetBackEndDisplay( __GLXclientState *cl, int s ); +extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s); + +static int swap_vec_element_size = 0; + +static void SendSwappedReply( ClientPtr client, + xGLXVendorPrivReply *reply, + char *buf, + int buf_size ) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->retval); + __GLX_SWAP_INT(&reply->size); + + if ( (buf_size == 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has single component - need to swap pad3 + */ + if (swap_vec_element_size == 2) { + __GLX_SWAP_SHORT(&reply->pad3); + } + else if (swap_vec_element_size == 4) { + __GLX_SWAP_INT(&reply->pad3); + __GLX_SWAP_INT(&reply->pad4); + } + else if (swap_vec_element_size == 8) { + __GLX_SWAP_DOUBLE(&reply->pad3); + } + } + else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has vector of elements which needs to be swapped + */ + int vsize = buf_size / swap_vec_element_size; + char *p = buf; + int i; + + for (i=0; ipad3); + __GLX_SWAP_INT(&reply->pad4); + __GLX_SWAP_INT(&reply->pad5); + __GLX_SWAP_INT(&reply->pad6); + + } + + WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)reply); + if (buf_size > 0) + WriteToClient(client, buf_size, (char *)buf); + +} + +int __glXVForwardSingleReq( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + xGLXVendorPrivateReq *be_req; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int buf_size; + int s; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXVendorPrivateReq; + buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqVendorPrivate(GLXVendorPrivate,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->vendorCode = req->vendorCode; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +int __glXVForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + xGLXVendorPrivateReq *be_req; + xGLXVendorPrivReply reply; + xGLXVendorPrivReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size; + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return __glXBadContext; + } + + pc += sz_xGLXVendorPrivateReq; + buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; + + dmxScreen = &dmxScreens[glxc->pScreen->myNum]; + dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum); + + /* + * send the request to the first back-end server + */ + LockDisplay(dpy); + GetReqVendorPrivate(GLXVendorPrivate,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->vendorCode = req->vendorCode; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag, glxc->pScreen->myNum); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + /* + * send the reply to the client + */ + memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply ); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXVForwardAllWithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + xGLXVendorPrivateReq *be_req; + xGLXVendorPrivReply reply; + xGLXVendorPrivReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size = 0; + int from_screen = 0; + int to_screen = 0; + int s; + + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXVendorPrivateReq; + buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; + + /* + * send the request to the first back-end server(s) + */ + for (s=to_screen; s>=from_screen; s--) { + dmxScreen = &dmxScreens[s]; + dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqVendorPrivate(GLXVendorPrivate,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->vendorCode = req->vendorCode; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + if (s > from_screen && be_buf_size > 0) { + free(be_buf); + } + } + + /* + * send the reply to the client + */ + memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply ); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXVForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + return( __glXVForwardSingleReq( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + diff --git a/xorg-server/hw/dmx/glxProxy/render2swap.c b/xorg-server/hw/dmx/glxProxy/render2swap.c index 34fd19624..81bb501ea 100644 --- a/xorg-server/hw/dmx/glxProxy/render2swap.c +++ b/xorg-server/hw/dmx/glxProxy/render2swap.c @@ -1,340 +1,286 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 - * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#include "glxserver.h" -#include "unpack.h" -#include "g_disptab.h" - -GLint __glEvalComputeK(GLenum target) -{ - switch (target) { - case GL_MAP1_VERTEX_4: - case GL_MAP1_COLOR_4: - case GL_MAP1_TEXTURE_COORD_4: - case GL_MAP2_VERTEX_4: - case GL_MAP2_COLOR_4: - case GL_MAP2_TEXTURE_COORD_4: - return 4; - case GL_MAP1_VERTEX_3: - case GL_MAP1_TEXTURE_COORD_3: - case GL_MAP1_NORMAL: - case GL_MAP2_VERTEX_3: - case GL_MAP2_TEXTURE_COORD_3: - case GL_MAP2_NORMAL: - return 3; - case GL_MAP1_TEXTURE_COORD_2: - case GL_MAP2_TEXTURE_COORD_2: - return 2; - case GL_MAP1_TEXTURE_COORD_1: - case GL_MAP2_TEXTURE_COORD_1: - case GL_MAP1_INDEX: - case GL_MAP2_INDEX: - return 1; - default: - return 0; - } -} - -void __glXDispSwap_Map1f(GLbyte *pc) -{ - GLint order, k; - GLfloat u1, u2, *points; - GLenum target; - GLint compsize; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_INT(pc + 0); - __GLX_SWAP_INT(pc + 12); - __GLX_SWAP_FLOAT(pc + 4); - __GLX_SWAP_FLOAT(pc + 8); - - target = *(GLenum *)(pc + 0); - order = *(GLint *)(pc + 12); - u1 = *(GLfloat *)(pc + 4); - u2 = *(GLfloat *)(pc + 8); - points = (GLfloat *)(pc + 16); - k = __glEvalComputeK(target); - - if (order <= 0 || k < 0) { - /* Erroneous command. */ - compsize = 0; - } else { - compsize = order * k; - } - __GLX_SWAP_FLOAT_ARRAY(points, compsize); - -} - -void __glXDispSwap_Map2f(GLbyte *pc) -{ - GLint uorder, vorder, ustride, vstride, k; - GLfloat u1, u2, v1, v2, *points; - GLenum target; - GLint compsize; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_INT(pc + 0); - __GLX_SWAP_INT(pc + 12); - __GLX_SWAP_INT(pc + 24); - __GLX_SWAP_FLOAT(pc + 4); - __GLX_SWAP_FLOAT(pc + 8); - __GLX_SWAP_FLOAT(pc + 16); - __GLX_SWAP_FLOAT(pc + 20); - - target = *(GLenum *)(pc + 0); - uorder = *(GLint *)(pc + 12); - vorder = *(GLint *)(pc + 24); - u1 = *(GLfloat *)(pc + 4); - u2 = *(GLfloat *)(pc + 8); - v1 = *(GLfloat *)(pc + 16); - v2 = *(GLfloat *)(pc + 20); - points = (GLfloat *)(pc + 28); - - k = __glEvalComputeK(target); - ustride = vorder * k; - vstride = k; - - if (vorder <= 0 || uorder <= 0 || k < 0) { - /* Erroneous command. */ - compsize = 0; - } else { - compsize = uorder * vorder * k; - } - __GLX_SWAP_FLOAT_ARRAY(points, compsize); - -} - -void __glXDispSwap_Map1d(GLbyte *pc) -{ - GLint order, k, compsize; - GLenum target; - GLdouble u1, u2, *points; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_DOUBLE(pc + 0); - __GLX_SWAP_DOUBLE(pc + 8); - __GLX_SWAP_INT(pc + 16); - __GLX_SWAP_INT(pc + 20); - - target = *(GLenum*) (pc + 16); - order = *(GLint*) (pc + 20); - k = __glEvalComputeK(target); - if (order <= 0 || k < 0) { - /* Erroneous command. */ - compsize = 0; - } else { - compsize = order * k; - } - __GLX_GET_DOUBLE(u1,pc); - __GLX_GET_DOUBLE(u2,pc+8); - __GLX_SWAP_DOUBLE_ARRAY(pc+24, compsize); - pc += 24; - -#ifdef __GLX_ALIGN64 - if (((unsigned long)pc) & 7) { - /* - ** Copy the doubles up 4 bytes, trashing the command but aligning - ** the data in the process - */ - __GLX_MEM_COPY(pc-4, pc, compsize*8); - points = (GLdouble*) (pc - 4); - } else { - points = (GLdouble*) pc; - } -#else - points = (GLdouble*) pc; -#endif -} - -void __glXDispSwap_Map2d(GLbyte *pc) -{ - GLdouble u1, u2, v1, v2, *points; - GLint uorder, vorder, ustride, vstride, k, compsize; - GLenum target; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_DOUBLE(pc + 0); - __GLX_SWAP_DOUBLE(pc + 8); - __GLX_SWAP_DOUBLE(pc + 16); - __GLX_SWAP_DOUBLE(pc + 24); - __GLX_SWAP_INT(pc + 32); - __GLX_SWAP_INT(pc + 36); - __GLX_SWAP_INT(pc + 40); - - target = *(GLenum *)(pc + 32); - uorder = *(GLint *)(pc + 36); - vorder = *(GLint *)(pc + 40); - k = __glEvalComputeK(target); - if (vorder <= 0 || uorder <= 0 || k < 0) { - /* Erroneous command. */ - compsize = 0; - } else { - compsize = uorder * vorder * k; - } - __GLX_GET_DOUBLE(u1,pc); - __GLX_GET_DOUBLE(u2,pc+8); - __GLX_GET_DOUBLE(v1,pc+16); - __GLX_GET_DOUBLE(v2,pc+24); - __GLX_SWAP_DOUBLE_ARRAY(pc+44, compsize); - pc += 44; - ustride = vorder * k; - vstride = k; - -#ifdef __GLX_ALIGN64 - if (((unsigned long)pc) & 7) { - /* - ** Copy the doubles up 4 bytes, trashing the command but aligning - ** the data in the process - */ - __GLX_MEM_COPY(pc-4, pc, compsize*8); - points = (GLdouble*) (pc - 4); - } else { - points = (GLdouble*) pc; - } -#else - points = (GLdouble*) pc; -#endif -} - -void __glXDispSwap_CallLists(GLbyte *pc) -{ - GLenum type; - GLsizei n; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - __GLX_SWAP_INT(pc + 4); - __GLX_SWAP_INT(pc + 0); - type = *(GLenum *)(pc + 4); - n = *(GLsizei *)(pc + 0); - - switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - case GL_2_BYTES: - case GL_3_BYTES: - case GL_4_BYTES: - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - __GLX_SWAP_SHORT_ARRAY(pc+8, n); - break; - case GL_INT: - case GL_UNSIGNED_INT: - __GLX_SWAP_INT_ARRAY(pc+8, n); - break; - case GL_FLOAT: - __GLX_SWAP_FLOAT_ARRAY(pc+8, n); - break; - } - -} - -static void swapArray(GLint numVals, GLenum datatype, - GLint stride, GLint numVertexes, GLbyte *pc) -{ - int i,j; - __GLX_DECLARE_SWAP_VARIABLES; - - switch (datatype) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - /* don't need to swap */ - return; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - for (i=0; inumVertexes); - __GLX_SWAP_INT(&hdr->numComponents); - __GLX_SWAP_INT(&hdr->primType); - - pc += sizeof(__GLXdispatchDrawArraysHeader); - compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; - - /* compute stride (same for all component arrays) */ - for (i=0; inumComponents; i++) { - __GLX_SWAP_INT(&compHeader[i].datatype); - __GLX_SWAP_INT(&compHeader[i].numVals); - __GLX_SWAP_INT(&compHeader[i].component); - - } - -} +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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 of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#include "glxserver.h" +#include "unpack.h" +#include "g_disptab.h" + +GLint __glEvalComputeK(GLenum target) +{ + switch (target) { + case GL_MAP1_VERTEX_4: + case GL_MAP1_COLOR_4: + case GL_MAP1_TEXTURE_COORD_4: + case GL_MAP2_VERTEX_4: + case GL_MAP2_COLOR_4: + case GL_MAP2_TEXTURE_COORD_4: + return 4; + case GL_MAP1_VERTEX_3: + case GL_MAP1_TEXTURE_COORD_3: + case GL_MAP1_NORMAL: + case GL_MAP2_VERTEX_3: + case GL_MAP2_TEXTURE_COORD_3: + case GL_MAP2_NORMAL: + return 3; + case GL_MAP1_TEXTURE_COORD_2: + case GL_MAP2_TEXTURE_COORD_2: + return 2; + case GL_MAP1_TEXTURE_COORD_1: + case GL_MAP2_TEXTURE_COORD_1: + case GL_MAP1_INDEX: + case GL_MAP2_INDEX: + return 1; + default: + return 0; + } +} + +void __glXDispSwap_Map1f(GLbyte *pc) +{ + GLint order, k; + GLfloat u1, u2, *points; + GLenum target; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + + target = *(GLenum *)(pc + 0); + order = *(GLint *)(pc + 12); + u1 = *(GLfloat *)(pc + 4); + u2 = *(GLfloat *)(pc + 8); + points = (GLfloat *)(pc + 16); + k = __glEvalComputeK(target); + + if (order <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = order * k; + } + __GLX_SWAP_FLOAT_ARRAY(points, compsize); + +} + +void __glXDispSwap_Map2f(GLbyte *pc) +{ + GLint uorder, vorder, ustride, vstride, k; + GLfloat u1, u2, v1, v2, *points; + GLenum target; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 24); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + __GLX_SWAP_FLOAT(pc + 16); + __GLX_SWAP_FLOAT(pc + 20); + + target = *(GLenum *)(pc + 0); + uorder = *(GLint *)(pc + 12); + vorder = *(GLint *)(pc + 24); + u1 = *(GLfloat *)(pc + 4); + u2 = *(GLfloat *)(pc + 8); + v1 = *(GLfloat *)(pc + 16); + v2 = *(GLfloat *)(pc + 20); + points = (GLfloat *)(pc + 28); + + k = __glEvalComputeK(target); + ustride = vorder * k; + vstride = k; + + if (vorder <= 0 || uorder <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = uorder * vorder * k; + } + __GLX_SWAP_FLOAT_ARRAY(points, compsize); + +} + +void __glXDispSwap_Map1d(GLbyte *pc) +{ + GLint order, k, compsize; + GLenum target; + GLdouble u1, u2, *points; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + + target = *(GLenum*) (pc + 16); + order = *(GLint*) (pc + 20); + k = __glEvalComputeK(target); + if (order <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = order * k; + } + __GLX_GET_DOUBLE(u1,pc); + __GLX_GET_DOUBLE(u2,pc+8); + __GLX_SWAP_DOUBLE_ARRAY(pc+24, compsize); + pc += 24; + +#ifdef __GLX_ALIGN64 + if (((unsigned long)pc) & 7) { + /* + ** Copy the doubles up 4 bytes, trashing the command but aligning + ** the data in the process + */ + __GLX_MEM_COPY(pc-4, pc, compsize*8); + points = (GLdouble*) (pc - 4); + } else { + points = (GLdouble*) pc; + } +#else + points = (GLdouble*) pc; +#endif +} + +void __glXDispSwap_Map2d(GLbyte *pc) +{ + GLdouble u1, u2, v1, v2, *points; + GLint uorder, vorder, ustride, vstride, k, compsize; + GLenum target; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_DOUBLE(pc + 16); + __GLX_SWAP_DOUBLE(pc + 24); + __GLX_SWAP_INT(pc + 32); + __GLX_SWAP_INT(pc + 36); + __GLX_SWAP_INT(pc + 40); + + target = *(GLenum *)(pc + 32); + uorder = *(GLint *)(pc + 36); + vorder = *(GLint *)(pc + 40); + k = __glEvalComputeK(target); + if (vorder <= 0 || uorder <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = uorder * vorder * k; + } + __GLX_GET_DOUBLE(u1,pc); + __GLX_GET_DOUBLE(u2,pc+8); + __GLX_GET_DOUBLE(v1,pc+16); + __GLX_GET_DOUBLE(v2,pc+24); + __GLX_SWAP_DOUBLE_ARRAY(pc+44, compsize); + pc += 44; + ustride = vorder * k; + vstride = k; + +#ifdef __GLX_ALIGN64 + if (((unsigned long)pc) & 7) { + /* + ** Copy the doubles up 4 bytes, trashing the command but aligning + ** the data in the process + */ + __GLX_MEM_COPY(pc-4, pc, compsize*8); + points = (GLdouble*) (pc - 4); + } else { + points = (GLdouble*) pc; + } +#else + points = (GLdouble*) pc; +#endif +} + +void __glXDispSwap_CallLists(GLbyte *pc) +{ + GLenum type; + GLsizei n; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 0); + type = *(GLenum *)(pc + 4); + n = *(GLsizei *)(pc + 0); + + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_2_BYTES: + case GL_3_BYTES: + case GL_4_BYTES: + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + __GLX_SWAP_SHORT_ARRAY(pc+8, n); + break; + case GL_INT: + case GL_UNSIGNED_INT: + __GLX_SWAP_INT_ARRAY(pc+8, n); + break; + case GL_FLOAT: + __GLX_SWAP_FLOAT_ARRAY(pc+8, n); + break; + } + +} + +void __glXDispSwap_DrawArrays(GLbyte *pc) +{ + __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *)pc; + __GLXdispatchDrawArraysComponentHeader *compHeader; + int i; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(&hdr->numVertexes); + __GLX_SWAP_INT(&hdr->numComponents); + __GLX_SWAP_INT(&hdr->primType); + + pc += sizeof(__GLXdispatchDrawArraysHeader); + compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; + + /* compute stride (same for all component arrays) */ + for (i=0; inumComponents; i++) { + __GLX_SWAP_INT(&compHeader[i].datatype); + __GLX_SWAP_INT(&compHeader[i].numVals); + __GLX_SWAP_INT(&compHeader[i].component); + + } + +} diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c index 8f61c4c72..1a5bf8a1c 100644 --- a/xorg-server/hw/xfree86/common/xf86Helper.c +++ b/xorg-server/hw/xfree86/common/xf86Helper.c @@ -1,2052 +1,2048 @@ -/* - * Copyright (c) 1997-2003 by The XFree86 Project, Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s) - * and author(s) shall not be used in advertising or otherwise to promote - * the sale, use or other dealings in this Software without prior written - * authorization from the copyright holder(s) and author(s). - */ - -/* - * Authors: Dirk Hohndel - * David Dawes - * ... and others - * - * This file includes the helper functions that the server provides for - * different drivers. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include -#include "os.h" -#include "servermd.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "propertyst.h" -#include "gcstruct.h" -#include "loaderProcs.h" -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86_OSlib.h" -#include "micmap.h" -#include "xf86DDC.h" -#include "xf86Xinput.h" -#include "xf86InPriv.h" -#include "mivalidate.h" -#include "xf86Crtc.h" - -/* For xf86GetClocks */ -#if defined(CSRG_BASED) || defined(__GNU__) -#define HAS_SETPRIORITY -#include -#endif - -static int xf86ScrnInfoPrivateCount = 0; - - -/* Add a pointer to a new DriverRec to xf86DriverList */ - -void -xf86AddDriver(DriverPtr driver, pointer module, int flags) -{ - /* Don't add null entries */ - if (!driver) - return; - - if (xf86DriverList == NULL) - xf86NumDrivers = 0; - - xf86NumDrivers++; - xf86DriverList = xnfrealloc(xf86DriverList, - xf86NumDrivers * sizeof(DriverPtr)); - xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec)); - if (flags & HaveDriverFuncs) - *xf86DriverList[xf86NumDrivers - 1] = *driver; - else { - (void) memset( xf86DriverList[xf86NumDrivers - 1], 0, - sizeof( DriverRec ) ); - (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver, - sizeof(DriverRec1)); - - } - xf86DriverList[xf86NumDrivers - 1]->module = module; - xf86DriverList[xf86NumDrivers - 1]->refCount = 0; -} - -void -xf86DeleteDriver(int drvIndex) -{ - if (xf86DriverList[drvIndex] - && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) { - if (xf86DriverList[drvIndex]->module) - UnloadModule(xf86DriverList[drvIndex]->module); - free(xf86DriverList[drvIndex]); - xf86DriverList[drvIndex] = NULL; - } -} - -/* Add a pointer to a new InputDriverRec to xf86InputDriverList */ - -void -xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags) -{ - /* Don't add null entries */ - if (!driver) - return; - - if (xf86InputDriverList == NULL) - xf86NumInputDrivers = 0; - - xf86NumInputDrivers++; - xf86InputDriverList = xnfrealloc(xf86InputDriverList, - xf86NumInputDrivers * sizeof(InputDriverPtr)); - xf86InputDriverList[xf86NumInputDrivers - 1] = - xnfalloc(sizeof(InputDriverRec)); - *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver; - xf86InputDriverList[xf86NumInputDrivers - 1]->module = module; -} - -void -xf86DeleteInputDriver(int drvIndex) -{ - if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module) - UnloadModule(xf86InputDriverList[drvIndex]->module); - free(xf86InputDriverList[drvIndex]); - xf86InputDriverList[drvIndex] = NULL; -} - -InputDriverPtr -xf86LookupInputDriver(const char *name) -{ - int i; - - for (i = 0; i < xf86NumInputDrivers; i++) { - if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && - xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0) - return xf86InputDriverList[i]; - } - return NULL; -} - -InputInfoPtr -xf86LookupInput(const char *name) -{ - InputInfoPtr p; - - for (p = xf86InputDevs; p != NULL; p = p->next) { - if (strcmp(name, p->name) == 0) - return p; - } - - return NULL; -} - -/* Allocate a new ScrnInfoRec in xf86Screens */ - -ScrnInfoPtr -xf86AllocateScreen(DriverPtr drv, int flags) -{ - int i; - - if (xf86Screens == NULL) - xf86NumScreens = 0; - - i = xf86NumScreens++; - xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr)); - xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); - xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */ - xf86Screens[i]->origIndex = i; /* This never changes */ - xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion), - xf86ScrnInfoPrivateCount); - /* - * EnableDisableFBAccess now gets initialized in InitOutput() - * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess; - */ - - xf86Screens[i]->drv = drv; - drv->refCount++; - xf86Screens[i]->module = DuplicateModule(drv->module, NULL); - - xf86Screens[i]->DriverFunc = drv->driverFunc; - - return xf86Screens[i]; -} - - -/* - * Remove an entry from xf86Screens. Ideally it should free all allocated - * data. To do this properly may require a driver hook. - */ - -void -xf86DeleteScreen(int scrnIndex, int flags) -{ - ScrnInfoPtr pScrn; - int i; - - /* First check if the screen is valid */ - if (xf86NumScreens == 0 || xf86Screens == NULL) - return; - - if (scrnIndex > xf86NumScreens - 1) - return; - - if (!(pScrn = xf86Screens[scrnIndex])) - return; - - /* If a FreeScreen function is defined, call it here */ - if (pScrn->FreeScreen != NULL) - pScrn->FreeScreen(scrnIndex, 0); - - while (pScrn->modes) - xf86DeleteMode(&pScrn->modes, pScrn->modes); - - while (pScrn->modePool) - xf86DeleteMode(&pScrn->modePool, pScrn->modePool); - - xf86OptionListFree(pScrn->options); - - if (pScrn->module) - UnloadModule(pScrn->module); - - if (pScrn->drv) - pScrn->drv->refCount--; - - free(pScrn->privates); - - xf86ClearEntityListForScreen(scrnIndex); - - free(pScrn); - - /* Move the other entries down, updating their scrnIndex fields */ - - xf86NumScreens--; - - for (i = scrnIndex; i < xf86NumScreens; i++) { - xf86Screens[i] = xf86Screens[i + 1]; - xf86Screens[i]->scrnIndex = i; - /* Also need to take care of the screen layout settings */ - } -} - -/* - * Allocate a private in ScrnInfoRec. - */ - -int -xf86AllocateScrnInfoPrivateIndex(void) -{ - int idx, i; - ScrnInfoPtr pScr; - DevUnion *nprivs; - - idx = xf86ScrnInfoPrivateCount++; - for (i = 0; i < xf86NumScreens; i++) { - pScr = xf86Screens[i]; - nprivs = xnfrealloc(pScr->privates, - xf86ScrnInfoPrivateCount * sizeof(DevUnion)); - /* Zero the new private */ - memset(&nprivs[idx], 0, sizeof(DevUnion)); - pScr->privates = nprivs; - } - return idx; -} - -Bool -xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad) -{ - int i; - - if (pScrn->numFormats >= MAXFORMATS) - return FALSE; - - if (bpp <= 0) { - if (depth == 1) - bpp = 1; - else if (depth <= 8) - bpp = 8; - else if (depth <= 16) - bpp = 16; - else if (depth <= 32) - bpp = 32; - else - return FALSE; - } - if (pad <= 0) - pad = BITMAP_SCANLINE_PAD; - - i = pScrn->numFormats++; - pScrn->formats[i].depth = depth; - pScrn->formats[i].bitsPerPixel = bpp; - pScrn->formats[i].scanlinePad = pad; - return TRUE; -} - -/* - * Set the depth we are using based on (in the following order of preference): - * - values given on the command line - * - values given in the config file - * - values provided by the driver - * - an overall default when nothing else is given - * - * Also find a Display subsection matching the depth/bpp found. - * - * Sets the following ScrnInfoRec fields: - * bitsPerPixel, pixmap24, depth, display, imageByteOrder, - * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats, - * formats, fbFormat. - */ - -/* Can the screen handle 24 bpp pixmaps */ -#define DO_PIX24(f) ((f & Support24bppFb) || \ - ((f & Support32bppFb) && (f & SupportConvert24to32))) - -/* Can the screen handle 32 bpp pixmaps */ -#define DO_PIX32(f) ((f & Support32bppFb) || \ - ((f & Support24bppFb) && (f & SupportConvert32to24))) - -/* Does the screen prefer 32bpp fb for 24bpp pixmaps */ -#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \ - && (f & PreferConvert24to32)) - -/* Does the screen prefer 24bpp fb for 32bpp pixmaps */ -#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \ - && (f & PreferConvert32to24)) - -/* Can the screen handle 32bpp pixmaps for 24bpp fb */ -#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24)) - -/* Can the screen handle 24bpp pixmaps for 32bpp fb */ -#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32)) - -#ifndef GLOBAL_DEFAULT_DEPTH -#define GLOBAL_DEFAULT_DEPTH 24 -#endif - -Bool -xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp, - int depth24flags) -{ - int i; - DispPtr disp; - Pix24Flags pix24 = xf86Info.pixmap24; - Bool nomatch = FALSE; - - scrp->bitsPerPixel = -1; - scrp->depth = -1; - scrp->pixmap24 = Pix24DontCare; - scrp->bitsPerPixelFrom = X_DEFAULT; - scrp->depthFrom = X_DEFAULT; - - if (xf86FbBpp > 0) { - scrp->bitsPerPixel = xf86FbBpp; - scrp->bitsPerPixelFrom = X_CMDLINE; - } - - if (xf86Depth > 0) { - scrp->depth = xf86Depth; - scrp->depthFrom = X_CMDLINE; - } - - if (xf86FbBpp < 0 && xf86Depth < 0) { - if (scrp->confScreen->defaultfbbpp > 0) { - scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp; - scrp->bitsPerPixelFrom = X_CONFIG; - } - if (scrp->confScreen->defaultdepth > 0) { - scrp->depth = scrp->confScreen->defaultdepth; - scrp->depthFrom = X_CONFIG; - } - - if (scrp->confScreen->defaultfbbpp <= 0 && - scrp->confScreen->defaultdepth <= 0) { - /* - * Check for DefaultDepth and DefaultFbBpp options in the - * Device sections. - */ - int i; - GDevPtr device; - Bool found = FALSE; - - for (i = 0; i < scrp->numEntities; i++) { - device = xf86GetDevFromEntity(scrp->entityList[i], - scrp->entityInstanceList[i]); - if (device && device->options) { - if (xf86FindOption(device->options, "DefaultDepth")) { - scrp->depth = xf86SetIntOption(device->options, - "DefaultDepth", -1); - scrp->depthFrom = X_CONFIG; - found = TRUE; - } - if (xf86FindOption(device->options, "DefaultFbBpp")) { - scrp->bitsPerPixel = xf86SetIntOption(device->options, - "DefaultFbBpp", - -1); - scrp->bitsPerPixelFrom = X_CONFIG; - found = TRUE; - } - } - if (found) - break; - } - } - } - - /* If none of these is set, pick a default */ - if (scrp->bitsPerPixel < 0 && scrp->depth < 0) { - if (fbbpp > 0 || depth > 0) { - if (fbbpp > 0) - scrp->bitsPerPixel = fbbpp; - if (depth > 0) - scrp->depth = depth; - } else { - scrp->depth = GLOBAL_DEFAULT_DEPTH; - } - } - - /* If any are not given, determine a default for the others */ - - if (scrp->bitsPerPixel < 0) { - /* The depth must be set */ - if (scrp->depth > -1) { - if (scrp->depth == 1) - scrp->bitsPerPixel = 1; - else if (scrp->depth <= 4) - scrp->bitsPerPixel = 4; - else if (scrp->depth <= 8) - scrp->bitsPerPixel = 8; - else if (scrp->depth <= 16) - scrp->bitsPerPixel = 16; - else if (scrp->depth <= 24) { - /* - * Figure out if a choice is possible based on the depth24 - * and pix24 flags. - */ - /* Check pix24 first */ - if (pix24 != Pix24DontCare) { - if (pix24 == Pix24Use32) { - if (DO_PIX32(depth24flags)) { - if (CHOOSE24FOR32(depth24flags)) - scrp->bitsPerPixel = 24; - else - scrp->bitsPerPixel = 32; - } else { - nomatch = TRUE; - } - } else if (pix24 == Pix24Use24) { - if (DO_PIX24(depth24flags)) { - if (CHOOSE32FOR24(depth24flags)) - scrp->bitsPerPixel = 32; - else - scrp->bitsPerPixel = 24; - } else { - nomatch = TRUE; - } - } - } else { - if (DO_PIX32(depth24flags)) { - if (CHOOSE24FOR32(depth24flags)) - scrp->bitsPerPixel = 24; - else - scrp->bitsPerPixel = 32; - } else if (DO_PIX24(depth24flags)) { - if (CHOOSE32FOR24(depth24flags)) - scrp->bitsPerPixel = 32; - else - scrp->bitsPerPixel = 24; - } - } - } else if (scrp->depth <= 32) - scrp->bitsPerPixel = 32; - else { - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Specified depth (%d) is greater than 32\n", - scrp->depth); - return FALSE; - } - } else { - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "xf86SetDepthBpp: internal error: depth and fbbpp" - " are both not set\n"); - return FALSE; - } - if (scrp->bitsPerPixel < 0) { - if (nomatch) - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Driver can't support depth 24 pixmap format (%d)\n", - PIX24TOBPP(pix24)); - else if ((depth24flags & (Support24bppFb | Support32bppFb)) == - NoDepth24Support) - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Driver can't support depth 24\n"); - else - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Can't find fbbpp for depth 24\n"); - return FALSE; - } - scrp->bitsPerPixelFrom = X_PROBED; - } - - if (scrp->depth <= 0) { - /* bitsPerPixel is already set */ - switch (scrp->bitsPerPixel) { - case 32: - scrp->depth = 24; - break; - default: - /* 1, 4, 8, 16 and 24 */ - scrp->depth = scrp->bitsPerPixel; - break; - } - scrp->depthFrom = X_PROBED; - } - - /* Sanity checks */ - if (scrp->depth < 1 || scrp->depth > 32) { - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Specified depth (%d) is not in the range 1-32\n", - scrp->depth); - return FALSE; - } - switch (scrp->bitsPerPixel) { - case 1: - case 4: - case 8: - case 16: - case 24: - case 32: - break; - default: - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Specified fbbpp (%d) is not a permitted value\n", - scrp->bitsPerPixel); - return FALSE; - } - if (scrp->depth > scrp->bitsPerPixel) { - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Specified depth (%d) is greater than the fbbpp (%d)\n", - scrp->depth, scrp->bitsPerPixel); - return FALSE; - } - - /* set scrp->pixmap24 if the driver isn't flexible */ - if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) { - scrp->pixmap24 = Pix24Use24; - } - if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) { - scrp->pixmap24 = Pix24Use32; - } - - /* - * Find the Display subsection matching the depth/fbbpp and initialise - * scrp->display with it. - */ - for (i = 0, disp = scrp->confScreen->displays; - i < scrp->confScreen->numdisplays; i++, disp++) { - if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel) - || (disp->depth == scrp->depth && disp->fbbpp <= 0) - || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) { - scrp->display = disp; - break; - } - } - - /* - * If an exact match can't be found, see if there is one with no - * depth or fbbpp specified. - */ - if (i == scrp->confScreen->numdisplays) { - for (i = 0, disp = scrp->confScreen->displays; - i < scrp->confScreen->numdisplays; i++, disp++) { - if (disp->depth <= 0 && disp->fbbpp <= 0) { - scrp->display = disp; - break; - } - } - } - - /* - * If all else fails, create a default one. - */ - if (i == scrp->confScreen->numdisplays) { - scrp->confScreen->numdisplays++; - scrp->confScreen->displays = - xnfrealloc(scrp->confScreen->displays, - scrp->confScreen->numdisplays * sizeof(DispRec)); - xf86DrvMsg(scrp->scrnIndex, X_INFO, - "Creating default Display subsection in Screen section\n" - "\t\"%s\" for depth/fbbpp %d/%d\n", - scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel); - memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec)); - scrp->confScreen->displays[i].blackColour.red = -1; - scrp->confScreen->displays[i].blackColour.green = -1; - scrp->confScreen->displays[i].blackColour.blue = -1; - scrp->confScreen->displays[i].whiteColour.red = -1; - scrp->confScreen->displays[i].whiteColour.green = -1; - scrp->confScreen->displays[i].whiteColour.blue = -1; - scrp->confScreen->displays[i].defaultVisual = -1; - scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *)); - scrp->confScreen->displays[i].modes[0] = NULL; - scrp->confScreen->displays[i].depth = depth; - scrp->confScreen->displays[i].fbbpp = fbbpp; - scrp->display = &scrp->confScreen->displays[i]; - } - - /* - * Setup defaults for the display-wide attributes the framebuffer will - * need. These defaults should eventually be set globally, and not - * dependent on the screens. - */ - scrp->imageByteOrder = IMAGE_BYTE_ORDER; - scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD; - if (scrp->depth < 8) { - /* Planar modes need these settings */ - scrp->bitmapScanlineUnit = 8; - scrp->bitmapBitOrder = MSBFirst; - } else { - scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; - scrp->bitmapBitOrder = BITMAP_BIT_ORDER; - } - - /* - * If an unusual depth is required, add it to scrp->formats. The formats - * for the common depths are handled globally in InitOutput - */ - switch (scrp->depth) { - case 1: - case 4: - case 8: - case 15: - case 16: - case 24: - /* Common depths. Nothing to do for them */ - break; - default: - if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) { - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Can't add pixmap format for depth %d\n", scrp->depth); - return FALSE; - } - } - - /* Initialise the framebuffer format for this screen */ - scrp->fbFormat.depth = scrp->depth; - scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel; - scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD; - - return TRUE; -} - -/* - * Print out the selected depth and bpp. - */ -void -xf86PrintDepthBpp(ScrnInfoPtr scrp) -{ - xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth); - xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel); -} - -/* - * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths - * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits. - */ -Bool -xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask) -{ - MessageType weightFrom = X_DEFAULT; - - scrp->weight.red = 0; - scrp->weight.green = 0; - scrp->weight.blue = 0; - - if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) { - scrp->weight = xf86Weight; - weightFrom = X_CMDLINE; - } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0 - && scrp->display->weight.blue > 0) { - scrp->weight = scrp->display->weight; - weightFrom = X_CONFIG; - } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) { - scrp->weight = weight; - } else { - switch (scrp->depth) { - case 1: - case 4: - case 8: - scrp->weight.red = scrp->weight.green = - scrp->weight.blue = scrp->rgbBits; - break; - case 15: - scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5; - break; - case 16: - scrp->weight.red = scrp->weight.blue = 5; - scrp->weight.green = 6; - break; - case 18: - scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6; - break; - case 24: - scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8; - break; - case 30: - scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10; - break; - } - } - - if (scrp->weight.red) - xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n", - (int)scrp->weight.red, (int)scrp->weight.green, - (int)scrp->weight.blue); - - if (scrp->depth > MAX_PSEUDO_DEPTH && - (scrp->depth != scrp->weight.red + scrp->weight.green + - scrp->weight.blue)) { - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Weight given (%d%d%d) is inconsistent with the " - "depth (%d)\n", - (int)scrp->weight.red, (int)scrp->weight.green, - (int)scrp->weight.blue, scrp->depth); - return FALSE; - } - if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) { - /* - * XXX Does this even mean anything for TrueColor visuals? - * If not, we shouldn't even be setting it here. However, this - * matches the behaviour of 3.x versions of XFree86. - */ - scrp->rgbBits = scrp->weight.red; - if (scrp->weight.green > scrp->rgbBits) - scrp->rgbBits = scrp->weight.green; - if (scrp->weight.blue > scrp->rgbBits) - scrp->rgbBits = scrp->weight.blue; - } - - /* Set the mask and offsets */ - if (mask.red == 0 || mask.green == 0 || mask.blue == 0) { - /* Default to a setting common to PC hardware */ - scrp->offset.red = scrp->weight.green + scrp->weight.blue; - scrp->offset.green = scrp->weight.blue; - scrp->offset.blue = 0; - scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red; - scrp->mask.green = ((1 << scrp->weight.green) - 1) - << scrp->offset.green; - scrp->mask.blue = (1 << scrp->weight.blue) - 1; - } else { - /* Initialise to the values passed */ - scrp->mask.red = mask.red; - scrp->mask.green = mask.green; - scrp->mask.blue = mask.blue; - scrp->offset.red = ffs(mask.red); - scrp->offset.green = ffs(mask.green); - scrp->offset.blue = ffs(mask.blue); - } - return TRUE; -} - -Bool -xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual) -{ - MessageType visualFrom = X_DEFAULT; - - if (defaultColorVisualClass >= 0) { - scrp->defaultVisual = defaultColorVisualClass; - visualFrom = X_CMDLINE; - } else if (scrp->display->defaultVisual >= 0) { - scrp->defaultVisual = scrp->display->defaultVisual; - visualFrom = X_CONFIG; - } else if (visual >= 0) { - scrp->defaultVisual = visual; - } else { - if (scrp->depth == 1) - scrp->defaultVisual = StaticGray; - else if (scrp->depth == 4) - scrp->defaultVisual = StaticColor; - else if (scrp->depth <= MAX_PSEUDO_DEPTH) - scrp->defaultVisual = PseudoColor; - else - scrp->defaultVisual = TrueColor; - } - switch (scrp->defaultVisual) { - case StaticGray: - case GrayScale: - case StaticColor: - case PseudoColor: - case TrueColor: - case DirectColor: - xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n", - xf86VisualNames[scrp->defaultVisual]); - return TRUE; - default: - - xf86DrvMsg(scrp->scrnIndex, X_ERROR, - "Invalid default visual class (%d)\n", scrp->defaultVisual); - return FALSE; - } -} - -#define TEST_GAMMA(g) \ - (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO - -#define SET_GAMMA(g) \ - (g) > GAMMA_ZERO ? (g) : 1.0 - -Bool -xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma) -{ - MessageType from = X_DEFAULT; -#if 0 - xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC); -#endif - if (TEST_GAMMA(xf86Gamma)) { - from = X_CMDLINE; - scrp->gamma.red = SET_GAMMA(xf86Gamma.red); - scrp->gamma.green = SET_GAMMA(xf86Gamma.green); - scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue); - } else if (TEST_GAMMA(scrp->monitor->gamma)) { - from = X_CONFIG; - scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red); - scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green); - scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue); -#if 0 - } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) { - from = X_PROBED; - scrp->gamma.red = SET_GAMMA(DDC->features.gamma); - scrp->gamma.green = SET_GAMMA(DDC->features.gamma); - scrp->gamma.blue = SET_GAMMA(DDC->features.gamma); - /* EDID structure version 2 gives optional seperate red, green & blue gamma values - * in bytes 0x57-0x59 */ -#endif - } else if (TEST_GAMMA(gamma)) { - scrp->gamma.red = SET_GAMMA(gamma.red); - scrp->gamma.green = SET_GAMMA(gamma.green); - scrp->gamma.blue = SET_GAMMA(gamma.blue); - } else { - scrp->gamma.red = 1.0; - scrp->gamma.green = 1.0; - scrp->gamma.blue = 1.0; - } - /* Pretend we succeeded if we support better a gamma system. - * This avoids a confusing message. - */ - if (xf86_crtc_supports_gamma(scrp)) - return TRUE; - xf86DrvMsg(scrp->scrnIndex, from, - "Using gamma correction (%.1f, %.1f, %.1f)\n", - scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue); - - return TRUE; -} - -#undef TEST_GAMMA -#undef SET_GAMMA - - -/* - * Set the DPI from the command line option. XXX should allow it to be - * calculated from the widthmm/heightmm values. - */ - -#undef MMPERINCH -#define MMPERINCH 25.4 - -void -xf86SetDpi(ScrnInfoPtr pScrn, int x, int y) -{ - MessageType from = X_DEFAULT; - xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC); - int ddcWidthmm, ddcHeightmm; - int widthErr, heightErr; - - /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */ - pScrn->widthmm = pScrn->monitor->widthmm; - pScrn->heightmm = pScrn->monitor->heightmm; - - if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) { - /* DDC gives display size in mm for individual modes, - * but cm for monitor - */ - ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */ - ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */ - } else { - ddcWidthmm = ddcHeightmm = 0; - } - - if (monitorResolution > 0) { - pScrn->xDpi = monitorResolution; - pScrn->yDpi = monitorResolution; - from = X_CMDLINE; - } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) { - from = X_CONFIG; - if (pScrn->widthmm > 0) { - pScrn->xDpi = - (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm); - } - if (pScrn->heightmm > 0) { - pScrn->yDpi = - (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm); - } - if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) - pScrn->yDpi = pScrn->xDpi; - if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) - pScrn->xDpi = pScrn->yDpi; - xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", - pScrn->widthmm, pScrn->heightmm); - - /* Warn if config and probe disagree about display size */ - if ( ddcWidthmm && ddcHeightmm ) { - if (pScrn->widthmm > 0) { - widthErr = abs(ddcWidthmm - pScrn->widthmm); - } else { - widthErr = 0; - } - if (pScrn->heightmm > 0) { - heightErr = abs(ddcHeightmm - pScrn->heightmm); - } else { - heightErr = 0; - } - if (widthErr>10 || heightErr>10) { - /* Should include config file name for monitor here */ - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n", - ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm); - } - } - } else if ( ddcWidthmm && ddcHeightmm ) { - from = X_PROBED; - xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", - ddcWidthmm, ddcHeightmm ); - pScrn->widthmm = ddcWidthmm; - pScrn->heightmm = ddcHeightmm; - if (pScrn->widthmm > 0) { - pScrn->xDpi = - (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm); - } - if (pScrn->heightmm > 0) { - pScrn->yDpi = - (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm); - } - if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) - pScrn->yDpi = pScrn->xDpi; - if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) - pScrn->xDpi = pScrn->yDpi; - } else { - if (x > 0) - pScrn->xDpi = x; - else - pScrn->xDpi = DEFAULT_DPI; - if (y > 0) - pScrn->yDpi = y; - else - pScrn->yDpi = DEFAULT_DPI; - } - xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n", - pScrn->xDpi, pScrn->yDpi); -} - -#undef MMPERINCH - - -void -xf86SetBlackWhitePixels(ScreenPtr pScreen) -{ - if (xf86FlipPixels) { - pScreen->whitePixel = 0; - pScreen->blackPixel = 1; - } else { - pScreen->whitePixel = 1; - pScreen->blackPixel = 0; - } -} - -/* - * xf86SetRootClip -- - * Enable or disable rendering to the screen by - * setting the root clip list and revalidating - * all of the windows - */ - -static void -xf86SetRootClip (ScreenPtr pScreen, Bool enable) -{ - WindowPtr pWin = pScreen->root; - WindowPtr pChild; - Bool WasViewable = (Bool)(pWin->viewable); - Bool anyMarked = FALSE; - WindowPtr pLayerWin; - BoxRec box; - - if (WasViewable) - { - for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) - { - (void) (*pScreen->MarkOverlappedWindows)(pChild, - pChild, - &pLayerWin); - } - (*pScreen->MarkWindow) (pWin); - anyMarked = TRUE; - if (pWin->valdata) - { - if (HasBorder (pWin)) - { - RegionPtr borderVisible; - - borderVisible = RegionCreate(NullBox, 1); - RegionSubtract(borderVisible, - &pWin->borderClip, &pWin->winSize); - pWin->valdata->before.borderVisible = borderVisible; - } - pWin->valdata->before.resized = TRUE; - } - } - - /* - * Use REGION_BREAK to avoid optimizations in ValidateTree - * that assume the root borderClip can't change well, normally - * it doesn't...) - */ - if (enable) - { - box.x1 = 0; - box.y1 = 0; - box.x2 = pScreen->width; - box.y2 = pScreen->height; - RegionInit(&pWin->winSize, &box, 1); - RegionInit(&pWin->borderSize, &box, 1); - if (WasViewable) - { - PixmapPtr pPixmap = (*pScreen->GetScreenPixmap) (pScreen); - box.x2 = pPixmap->drawable.width; - box.y2 = pPixmap->drawable.height; - RegionReset(&pWin->borderClip, &box); - } - pWin->drawable.width = pScreen->width; - pWin->drawable.height = pScreen->height; - RegionBreak(&pWin->clipList); - } - else - { - RegionEmpty(&pWin->borderClip); - RegionBreak(&pWin->clipList); - } - - ResizeChildrenWinSize (pWin, 0, 0, 0, 0); - - if (WasViewable) - { - if (pWin->firstChild) - { - anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, - pWin->firstChild, - (WindowPtr *)NULL); - } - else - { - (*pScreen->MarkWindow) (pWin); - anyMarked = TRUE; - } - - - if (anyMarked) - (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); - } - - if (WasViewable) - { - if (anyMarked) - (*pScreen->HandleExposures)(pWin); - if (anyMarked && pScreen->PostValidateTree) - (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); - } - if (pWin->realized) - WindowsRestructured (); - FlushAllOutput (); -} - -/* - * Function to enable/disable access to the frame buffer - * - * This is used when VT switching and when entering/leaving DGA direct mode. - * - * This has been rewritten again to eliminate the saved pixmap. The - * devPrivate field in the screen pixmap is set to NULL to catch code - * accidentally referencing the frame buffer while the X server is not - * supposed to touch it. - * - * Here, we exchange the pixmap private data, rather than the pixmaps - * themselves to avoid having to find and change any references to the screen - * pixmap such as GC's, window privates etc. This also means that this code - * does not need to know exactly how the pixmap pixels are accessed. Further, - * this exchange is >not< done through the screen's ModifyPixmapHeader() - * vector. This means the called frame buffer code layers can determine - * whether they are switched in or out by keeping track of the root pixmap's - * private data, and therefore don't need to access pScrnInfo->vtSema. - */ -void -xf86EnableDisableFBAccess(int scrnIndex, Bool enable) -{ - ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex]; - ScreenPtr pScreen = pScrnInfo->pScreen; - PixmapPtr pspix; - - pspix = (*pScreen->GetScreenPixmap) (pScreen); - if (enable) - { - /* - * Restore all of the clip lists on the screen - */ - if (!xf86Resetting) - xf86SetRootClip (pScreen, TRUE); - } - else - { - /* - * Empty all of the clip lists on the screen - */ - xf86SetRootClip (pScreen, FALSE); - } -} - -/* Print driver messages in the standard format */ - -#undef PREFIX_SIZE -#define PREFIX_SIZE 14 - -void -xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, - va_list args) -{ - char *tmpFormat; - - /* Prefix the scrnIndex name to the format string. */ - if (scrnIndex >= 0 && scrnIndex < xf86NumScreens && - xf86Screens[scrnIndex]->name) { - tmpFormat = malloc(strlen(format) + - strlen(xf86Screens[scrnIndex]->name) + - PREFIX_SIZE + 1); - if (!tmpFormat) - return; - - snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ", - xf86Screens[scrnIndex]->name, scrnIndex); - - strcat(tmpFormat, format); - LogVMessageVerb(type, verb, tmpFormat, args); - free(tmpFormat); - } else - LogVMessageVerb(type, verb, format, args); -} -#undef PREFIX_SIZE - -/* Print driver messages, with verbose level specified directly */ -void -xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, - ...) -{ - va_list ap; - - va_start(ap, format); - xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap); - va_end(ap); -} - -/* Print driver messages, with verbose level of 1 (default) */ -void -xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap); - va_end(ap); -} - -/* Print input driver messages in the standard format of - : : */ -void -xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format, - va_list args) -{ - char *msg; - - if (asprintf(&msg, "%s: %s: %s", dev->drv->driverName, dev->name, format) - == -1) { - LogVMessageVerb(type, verb, "%s", args); - } else { - LogVMessageVerb(type, verb, msg, args); - free(msg); - } -} - -/* Print input driver message, with verbose level specified directly */ -void -xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format, - ...) -{ - va_list ap; - - va_start(ap, format); - xf86VIDrvMsgVerb(dev, type, verb, format, ap); - va_end(ap); -} - -/* Print input driver messages, with verbose level of 1 (default) */ -void -xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - xf86VIDrvMsgVerb(dev, type, 1, format, ap); - va_end(ap); -} - - -/* Print non-driver messages with verbose level specified directly */ -void -xf86MsgVerb(MessageType type, int verb, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - LogVMessageVerb(type, verb, format, ap); - va_end(ap); -} - -/* Print non-driver messages with verbose level of 1 (default) */ -void -xf86Msg(MessageType type, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - LogVMessageVerb(type, 1, format, ap); - va_end(ap); -} - -/* Just like ErrorF, but with the verbose level checked */ -void -xf86ErrorFVerb(int verb, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - if (xf86Verbose >= verb || xf86LogVerbose >= verb) - LogVWrite(verb, format, ap); - va_end(ap); -} - -/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */ -void -xf86ErrorF(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - if (xf86Verbose >= 1 || xf86LogVerbose >= 1) - LogVWrite(1, format, ap); - va_end(ap); -} - - -void -xf86LogInit(void) -{ - char *lf = NULL; - -#define LOGSUFFIX ".log" -#define LOGOLDSUFFIX ".old" - - /* Get the log file name */ - if (xf86LogFileFrom == X_DEFAULT) { - /* Append the display number and ".log" */ - if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1) - FatalError("Cannot allocate space for the log file name\n"); - xf86LogFile = lf; - } - - xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX); - xf86LogFileWasOpened = TRUE; - - xf86SetVerbosity(xf86Verbose); - xf86SetLogVerbosity(xf86LogVerbose); - -#undef LOGSUFFIX -#undef LOGOLDSUFFIX - - free(lf); -} - -void -xf86CloseLog(void) -{ - LogClose(); -} - - -/* - * Drivers can use these for using their own SymTabRecs. - */ - -const char * -xf86TokenToString(SymTabPtr table, int token) -{ - int i; - - for (i = 0; table[i].token >= 0 && table[i].token != token; i++) - ; - - if (table[i].token < 0) - return NULL; - else - return table[i].name; -} - -int -xf86StringToToken(SymTabPtr table, const char *string) -{ - int i; - - if (string == NULL) - return -1; - - for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++) - ; - - return table[i].token; -} - -/* - * helper to display the clocks found on a card - */ -void -xf86ShowClocks(ScrnInfoPtr scrp, MessageType from) -{ - int j; - - xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:"); - for (j=0; j < scrp->numClocks; j++) { - if ((j % 4) == 0) { - xf86ErrorF("\n"); - xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:"); - } - xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0); - } - xf86ErrorF("\n"); -} - - -/* - * This prints out the driver identify message, including the names of - * the supported chipsets. - * - * XXX This makes assumptions about the line width, etc. Maybe we could - * use a more general "pretty print" function for messages. - */ -void -xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips) -{ - int len, i; - - len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2; - xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg); - for (i = 0; chips[i].name != NULL; i++) { - if (i != 0) { - xf86ErrorF(","); - len++; - } - if (len + 2 + strlen(chips[i].name) < 78) { - xf86ErrorF(" "); - len++; - } else { - xf86ErrorF("\n\t"); - len = 8; - } - xf86ErrorF("%s", chips[i].name); - len += strlen(chips[i].name); - } - xf86ErrorF("\n"); -} - - -int -xf86MatchDevice(const char *drivername, GDevPtr **sectlist) -{ - GDevPtr gdp, *pgdp = NULL; - confScreenPtr screensecptr; - int i,j; - - if (sectlist) - *sectlist = NULL; - - /* - * This can happen when running Xorg -showopts and a module like ati - * or vmware tries to load its submodules when xf86ConfigLayout is empty - */ - if (!xf86ConfigLayout.screens) - return 0; - - /* - * This is a very important function that matches the device sections - * as they show up in the config file with the drivers that the server - * loads at run time. - * - * ChipProbe can call - * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist) - * with its driver name. The function allocates an array of GDevPtr and - * returns this via sectlist and returns the number of elements in - * this list as return value. 0 means none found, -1 means fatal error. - * - * It can figure out which of the Device sections to use for which card - * (using things like the Card statement, etc). For single headed servers - * there will of course be just one such Device section. - */ - i = 0; - - /* - * first we need to loop over all the Screens sections to get to all - * 'active' device sections - */ - for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) { - screensecptr = xf86ConfigLayout.screens[j].screen; - if ((screensecptr->device->driver != NULL) - && (xf86NameCmp( screensecptr->device->driver,drivername) == 0) - && (! screensecptr->device->claimed)) { - /* - * we have a matching driver that wasn't claimed, yet - */ - pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); - pgdp[i++] = screensecptr->device; - } - } - - /* Then handle the inactive devices */ - j = 0; - while (xf86ConfigLayout.inactives[j].identifier) { - gdp = &xf86ConfigLayout.inactives[j]; - if (gdp->driver && !gdp->claimed && - !xf86NameCmp(gdp->driver,drivername)) { - /* we have a matching driver that wasn't claimed yet */ - pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); - pgdp[i++] = gdp; - } - j++; - } - - /* - * make the array NULL terminated and return its address - */ - if (i) - pgdp[i] = NULL; - - if (sectlist) - *sectlist = pgdp; - else - free(pgdp); - return i; -} - -/* - * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ... - */ -void -xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int), - void (*ProtectRegs)(ScrnInfoPtr, Bool), - void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg, - int maskval, int knownclkindex, int knownclkvalue) -{ - register int status = vertsyncreg; - unsigned long i, cnt, rcnt, sync; - - /* First save registers that get written on */ - (*ClockFunc)(pScrn, CLK_REG_SAVE); - - if (num > MAXCLOCKS) - num = MAXCLOCKS; - - for (i = 0; i < num; i++) - { - if (ProtectRegs) - (*ProtectRegs)(pScrn, TRUE); - if (!(*ClockFunc)(pScrn, i)) - { - pScrn->clock[i] = -1; - continue; - } - if (ProtectRegs) - (*ProtectRegs)(pScrn, FALSE); - if (BlankScreen) - (*BlankScreen)(pScrn, FALSE); - - usleep(50000); /* let VCO stabilise */ - - cnt = 0; - sync = 200000; - - while ((inb(status) & maskval) == 0x00) - if (sync-- == 0) goto finish; - /* Something appears to be happening, so reset sync count */ - sync = 200000; - while ((inb(status) & maskval) == maskval) - if (sync-- == 0) goto finish; - /* Something appears to be happening, so reset sync count */ - sync = 200000; - while ((inb(status) & maskval) == 0x00) - if (sync-- == 0) goto finish; - - for (rcnt = 0; rcnt < 5; rcnt++) - { - while (!(inb(status) & maskval)) - cnt++; - while ((inb(status) & maskval)) - cnt++; - } - -finish: - pScrn->clock[i] = cnt ? cnt : -1; - if (BlankScreen) - (*BlankScreen)(pScrn, TRUE); - } - - for (i = 0; i < num; i++) - { - if (i != knownclkindex) - { - if (pScrn->clock[i] == -1) - { - pScrn->clock[i] = 0; - } - else - { - pScrn->clock[i] = (int)(0.5 + - (((float)knownclkvalue) * pScrn->clock[knownclkindex]) / - (pScrn->clock[i])); - /* Round to nearest 10KHz */ - pScrn->clock[i] += 5; - pScrn->clock[i] /= 10; - pScrn->clock[i] *= 10; - } - } - } - - pScrn->clock[knownclkindex] = knownclkvalue; - pScrn->numClocks = num; - - /* Restore registers that were written on */ - (*ClockFunc)(pScrn, CLK_REG_RESTORE); -} - -const char * -xf86GetVisualName(int visual) -{ - if (visual < 0 || visual > DirectColor) - return NULL; - - return xf86VisualNames[visual]; -} - - -int -xf86GetVerbosity(void) -{ - return max(xf86Verbose, xf86LogVerbose); -} - -Pix24Flags -xf86GetPix24(void) -{ - return xf86Info.pixmap24; -} - - -int -xf86GetDepth(void) -{ - return xf86Depth; -} - - -rgb -xf86GetWeight(void) -{ - return xf86Weight; -} - - -Gamma -xf86GetGamma(void) -{ - return xf86Gamma; -} - - -Bool -xf86GetFlipPixels(void) -{ - return xf86FlipPixels; -} - - -const char * -xf86GetServerName(void) -{ - return xf86ServerName; -} - - -Bool -xf86ServerIsExiting(void) -{ - return (dispatchException & DE_TERMINATE) == DE_TERMINATE; -} - - -Bool -xf86ServerIsResetting(void) -{ - return xf86Resetting; -} - - -Bool -xf86ServerIsInitialising(void) -{ - return xf86Initialising; -} - - -Bool -xf86ServerIsOnlyDetecting(void) -{ - return xf86DoConfigure; -} - - -Bool -xf86CaughtSignal(void) -{ - return xf86Info.caughtSignal; -} - - -Bool -xf86GetVidModeAllowNonLocal(void) -{ - return xf86Info.vidModeAllowNonLocal; -} - - -Bool -xf86GetVidModeEnabled(void) -{ - return xf86Info.vidModeEnabled; -} - -Bool -xf86GetModInDevAllowNonLocal(void) -{ - return xf86Info.miscModInDevAllowNonLocal; -} - - -Bool -xf86GetModInDevEnabled(void) -{ - return xf86Info.miscModInDevEnabled; -} - - -Bool -xf86GetAllowMouseOpenFail(void) -{ - return xf86Info.allowMouseOpenFail; -} - - -Bool -xf86IsPc98(void) -{ -#if SUPPORT_PC98 - return xf86Info.pc98; -#else - return FALSE; -#endif -} - -void -xf86DisableRandR(void) -{ - xf86Info.disableRandR = TRUE; - xf86Info.randRFrom = X_PROBED; -} - -CARD32 -xf86GetModuleVersion(pointer module) -{ - return (CARD32)LoaderGetModuleVersion(module); -} - -pointer -xf86LoadDrvSubModule(DriverPtr drv, const char *name) -{ - pointer ret; - int errmaj = 0, errmin = 0; - - ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL, - &errmaj, &errmin); - if (!ret) - LoaderErrorMsg(NULL, name, errmaj, errmin); - return ret; -} - -pointer -xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name) -{ - pointer ret; - int errmaj = 0, errmin = 0; - - ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL, - &errmaj, &errmin); - if (!ret) - LoaderErrorMsg(pScrn->name, name, errmaj, errmin); - return ret; -} - -/* - * xf86LoadOneModule loads a single module. - */ -pointer -xf86LoadOneModule(char *name, pointer opt) -{ - int errmaj, errmin; - char *Name; - pointer mod; - - if (!name) - return NULL; - - /* Normalise the module name */ - Name = xf86NormalizeName(name); - - /* Skip empty names */ - if (Name == NULL) - return NULL; - if (*Name == '\0') { - free(Name); - return NULL; - } - - mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin); - if (!mod) - LoaderErrorMsg(NULL, Name, errmaj, errmin); - free(Name); - return mod; -} - -void -xf86UnloadSubModule(pointer mod) -{ - /* - * This is disabled for now. The loader isn't smart enough yet to undo - * relocations. - */ -#if 0 - UnloadSubModule(mod); -#endif -} - -Bool -xf86LoaderCheckSymbol(const char *name) -{ - return LoaderSymbol(name) != NULL; -} - -typedef enum { - OPTION_BACKING_STORE -} BSOpts; - -static const OptionInfoRec BSOptions[] = { - { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, OPTV_NONE, {0}, FALSE } -}; - -void -xf86SetBackingStore(ScreenPtr pScreen) -{ - Bool useBS = FALSE; - MessageType from = X_DEFAULT; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - OptionInfoPtr options; - - options = xnfalloc(sizeof(BSOptions)); - (void)memcpy(options, BSOptions, sizeof(BSOptions)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); - - /* check for commandline option here */ - if (xf86bsEnableFlag) { - from = X_CMDLINE; - useBS = TRUE; - } else if (xf86bsDisableFlag) { - from = X_CMDLINE; - useBS = FALSE; - } else { - if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS)) - from = X_CONFIG; - } - free(options); - pScreen->backingStoreSupport = useBS ? Always : NotUseful; - if (serverGeneration == 1) - xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n", - useBS ? "enabled" : "disabled"); -} - - -typedef enum { - OPTION_SILKEN_MOUSE -} SMOpts; - -static const OptionInfoRec SMOptions[] = { - { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, OPTV_NONE, {0}, FALSE } -}; - -void -xf86SetSilkenMouse (ScreenPtr pScreen) -{ - Bool useSM = TRUE; - MessageType from = X_DEFAULT; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - OptionInfoPtr options; - - options = xnfalloc(sizeof(SMOptions)); - (void)memcpy(options, SMOptions, sizeof(SMOptions)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); - - /* check for commandline option here */ - /* disable if screen shares resources */ - /* TODO VGA arb disable silken mouse */ - if (xf86silkenMouseDisableFlag) { - from = X_CMDLINE; - useSM = FALSE; - } else { - if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM)) - from = X_CONFIG; - } - free(options); - /* - * XXX quick hack to report correctly for OSs that can't do SilkenMouse - * yet. Should handle this differently so that alternate async methods - * work correctly with this too. - */ - pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported(); - if (serverGeneration == 1) - xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n", - pScrn->silkenMouse ? "enabled" : "disabled"); -} - -/* Wrote this function for the PM2 Xv driver, preliminary. */ - -pointer -xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name, - char **adaptor_name, pointer *adaptor_options) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - confXvAdaptorPtr adaptor; - int i; - - if (adaptor_index >= pScrn->confScreen->numxvadaptors) { - if (adaptor_name) *adaptor_name = NULL; - if (adaptor_options) *adaptor_options = NULL; - return NULL; - } - - adaptor = &pScrn->confScreen->xvadaptors[adaptor_index]; - if (adaptor_name) *adaptor_name = adaptor->identifier; - if (adaptor_options) *adaptor_options = adaptor->options; - - for (i = 0; i < adaptor->numports; i++) - if (!xf86NameCmp(adaptor->ports[i].identifier, port_name)) - return adaptor->ports[i].options; - - return NULL; -} - -/* Rather than duplicate loader's get OS function, just include it directly */ -#define LoaderGetOS xf86GetOS -#include "loader/os.c" - -static void -xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init, - EntityProc enter, EntityProc leave, pointer private) -{ - ScrnInfoPtr pScrn; - - if ((pScrn = xf86FindScreenForEntity(pEnt->index))) - xf86RemoveEntityFromScreen(pScrn,pEnt->index); - xf86SetEntityFuncs(pEnt->index,init,enter,leave,private); -} - -ScrnInfoPtr -xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex, - EntityProc init, EntityProc enter, EntityProc leave, - pointer private) -{ - EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex); - if (!pEnt) return pScrn; - - if (!(pEnt->location.type == BUS_NONE)) { - free(pEnt); - return pScrn; - } - - if (!pEnt->active) { - xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private); - free(pEnt); - return pScrn; - } - - if (!pScrn) - pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag); - xf86AddEntityToScreen(pScrn,entityIndex); - - xf86SetEntityFuncs(entityIndex,init,enter,leave,private); - - return pScrn; -} - -Bool -xf86IsScreenPrimary(int scrnIndex) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - int i; - - for (i=0 ; i < pScrn->numEntities; i++) { - if (xf86IsEntityPrimary(i)) - return TRUE; - } - return FALSE; -} - -int -xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type, - int format, unsigned long len, pointer value ) -{ - RootWinPropPtr pNewProp = NULL, pRegProp; - int i; - Bool existing = FALSE; - - DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n", - ScrnIndex, property, type, format, len, value); - - if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) { - return BadMatch; - } - - if (xf86RegisteredPropertiesTable && - xf86RegisteredPropertiesTable[ScrnIndex]) { - for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex]; - pNewProp; pNewProp = pNewProp->next) { - if (strcmp(pNewProp->name, NameForAtom(property)) == 0) - break; - } - } - - if (!pNewProp) { - if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) { - return BadAlloc; - } - /* - * We will put this property at the end of the list so that - * the changes are made in the order they were requested. - */ - pNewProp->next = NULL; - } else { - free(pNewProp->name); - existing = TRUE; - } - - pNewProp->name = xnfstrdup(NameForAtom(property)); - pNewProp->type = type; - pNewProp->format = format; - pNewProp->size = len; - pNewProp->data = value; - - DebugF("new property filled\n"); - - if (NULL==xf86RegisteredPropertiesTable) { - DebugF("creating xf86RegisteredPropertiesTable[] size %d\n", - xf86NumScreens); - if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) { - return BadAlloc; - } - for (i=0; inext != NULL) { - DebugF("- next %p\n", (void *)pRegProp); - pRegProp = pRegProp->next; - } - pRegProp->next = pNewProp; - } - } - DebugF("xf86RegisterRootWindowProperty succeeded\n"); - return Success; -} - -Bool -xf86IsUnblank(int mode) -{ - switch(mode) { - case SCREEN_SAVER_OFF: - case SCREEN_SAVER_FORCER: - return TRUE; - case SCREEN_SAVER_ON: - case SCREEN_SAVER_CYCLE: - return FALSE; - default: - xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode); - return TRUE; - } -} - -void -xf86MotionHistoryAllocate(InputInfoPtr pInfo) -{ - AllocateMotionHistory(pInfo->dev); -} +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* + * Authors: Dirk Hohndel + * David Dawes + * ... and others + * + * This file includes the helper functions that the server provides for + * different drivers. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include +#include "os.h" +#include "servermd.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "propertyst.h" +#include "gcstruct.h" +#include "loaderProcs.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "micmap.h" +#include "xf86DDC.h" +#include "xf86Xinput.h" +#include "xf86InPriv.h" +#include "mivalidate.h" +#include "xf86Crtc.h" + +/* For xf86GetClocks */ +#if defined(CSRG_BASED) || defined(__GNU__) +#define HAS_SETPRIORITY +#include +#endif + +static int xf86ScrnInfoPrivateCount = 0; + + +/* Add a pointer to a new DriverRec to xf86DriverList */ + +void +xf86AddDriver(DriverPtr driver, pointer module, int flags) +{ + /* Don't add null entries */ + if (!driver) + return; + + if (xf86DriverList == NULL) + xf86NumDrivers = 0; + + xf86NumDrivers++; + xf86DriverList = xnfrealloc(xf86DriverList, + xf86NumDrivers * sizeof(DriverPtr)); + xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec)); + if (flags & HaveDriverFuncs) + *xf86DriverList[xf86NumDrivers - 1] = *driver; + else { + (void) memset( xf86DriverList[xf86NumDrivers - 1], 0, + sizeof( DriverRec ) ); + (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver, + sizeof(DriverRec1)); + + } + xf86DriverList[xf86NumDrivers - 1]->module = module; + xf86DriverList[xf86NumDrivers - 1]->refCount = 0; +} + +void +xf86DeleteDriver(int drvIndex) +{ + if (xf86DriverList[drvIndex] + && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) { + if (xf86DriverList[drvIndex]->module) + UnloadModule(xf86DriverList[drvIndex]->module); + free(xf86DriverList[drvIndex]); + xf86DriverList[drvIndex] = NULL; + } +} + +/* Add a pointer to a new InputDriverRec to xf86InputDriverList */ + +void +xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags) +{ + /* Don't add null entries */ + if (!driver) + return; + + if (xf86InputDriverList == NULL) + xf86NumInputDrivers = 0; + + xf86NumInputDrivers++; + xf86InputDriverList = xnfrealloc(xf86InputDriverList, + xf86NumInputDrivers * sizeof(InputDriverPtr)); + xf86InputDriverList[xf86NumInputDrivers - 1] = + xnfalloc(sizeof(InputDriverRec)); + *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver; + xf86InputDriverList[xf86NumInputDrivers - 1]->module = module; +} + +void +xf86DeleteInputDriver(int drvIndex) +{ + if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module) + UnloadModule(xf86InputDriverList[drvIndex]->module); + free(xf86InputDriverList[drvIndex]); + xf86InputDriverList[drvIndex] = NULL; +} + +InputDriverPtr +xf86LookupInputDriver(const char *name) +{ + int i; + + for (i = 0; i < xf86NumInputDrivers; i++) { + if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && + xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0) + return xf86InputDriverList[i]; + } + return NULL; +} + +InputInfoPtr +xf86LookupInput(const char *name) +{ + InputInfoPtr p; + + for (p = xf86InputDevs; p != NULL; p = p->next) { + if (strcmp(name, p->name) == 0) + return p; + } + + return NULL; +} + +/* Allocate a new ScrnInfoRec in xf86Screens */ + +ScrnInfoPtr +xf86AllocateScreen(DriverPtr drv, int flags) +{ + int i; + + if (xf86Screens == NULL) + xf86NumScreens = 0; + + i = xf86NumScreens++; + xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr)); + xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); + xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */ + xf86Screens[i]->origIndex = i; /* This never changes */ + xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion), + xf86ScrnInfoPrivateCount); + /* + * EnableDisableFBAccess now gets initialized in InitOutput() + * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess; + */ + + xf86Screens[i]->drv = drv; + drv->refCount++; + xf86Screens[i]->module = DuplicateModule(drv->module, NULL); + + xf86Screens[i]->DriverFunc = drv->driverFunc; + + return xf86Screens[i]; +} + + +/* + * Remove an entry from xf86Screens. Ideally it should free all allocated + * data. To do this properly may require a driver hook. + */ + +void +xf86DeleteScreen(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn; + int i; + + /* First check if the screen is valid */ + if (xf86NumScreens == 0 || xf86Screens == NULL) + return; + + if (scrnIndex > xf86NumScreens - 1) + return; + + if (!(pScrn = xf86Screens[scrnIndex])) + return; + + /* If a FreeScreen function is defined, call it here */ + if (pScrn->FreeScreen != NULL) + pScrn->FreeScreen(scrnIndex, 0); + + while (pScrn->modes) + xf86DeleteMode(&pScrn->modes, pScrn->modes); + + while (pScrn->modePool) + xf86DeleteMode(&pScrn->modePool, pScrn->modePool); + + xf86OptionListFree(pScrn->options); + + if (pScrn->module) + UnloadModule(pScrn->module); + + if (pScrn->drv) + pScrn->drv->refCount--; + + free(pScrn->privates); + + xf86ClearEntityListForScreen(scrnIndex); + + free(pScrn); + + /* Move the other entries down, updating their scrnIndex fields */ + + xf86NumScreens--; + + for (i = scrnIndex; i < xf86NumScreens; i++) { + xf86Screens[i] = xf86Screens[i + 1]; + xf86Screens[i]->scrnIndex = i; + /* Also need to take care of the screen layout settings */ + } +} + +/* + * Allocate a private in ScrnInfoRec. + */ + +int +xf86AllocateScrnInfoPrivateIndex(void) +{ + int idx, i; + ScrnInfoPtr pScr; + DevUnion *nprivs; + + idx = xf86ScrnInfoPrivateCount++; + for (i = 0; i < xf86NumScreens; i++) { + pScr = xf86Screens[i]; + nprivs = xnfrealloc(pScr->privates, + xf86ScrnInfoPrivateCount * sizeof(DevUnion)); + /* Zero the new private */ + memset(&nprivs[idx], 0, sizeof(DevUnion)); + pScr->privates = nprivs; + } + return idx; +} + +Bool +xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad) +{ + int i; + + if (pScrn->numFormats >= MAXFORMATS) + return FALSE; + + if (bpp <= 0) { + if (depth == 1) + bpp = 1; + else if (depth <= 8) + bpp = 8; + else if (depth <= 16) + bpp = 16; + else if (depth <= 32) + bpp = 32; + else + return FALSE; + } + if (pad <= 0) + pad = BITMAP_SCANLINE_PAD; + + i = pScrn->numFormats++; + pScrn->formats[i].depth = depth; + pScrn->formats[i].bitsPerPixel = bpp; + pScrn->formats[i].scanlinePad = pad; + return TRUE; +} + +/* + * Set the depth we are using based on (in the following order of preference): + * - values given on the command line + * - values given in the config file + * - values provided by the driver + * - an overall default when nothing else is given + * + * Also find a Display subsection matching the depth/bpp found. + * + * Sets the following ScrnInfoRec fields: + * bitsPerPixel, pixmap24, depth, display, imageByteOrder, + * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats, + * formats, fbFormat. + */ + +/* Can the screen handle 24 bpp pixmaps */ +#define DO_PIX24(f) ((f & Support24bppFb) || \ + ((f & Support32bppFb) && (f & SupportConvert24to32))) + +/* Can the screen handle 32 bpp pixmaps */ +#define DO_PIX32(f) ((f & Support32bppFb) || \ + ((f & Support24bppFb) && (f & SupportConvert32to24))) + +/* Does the screen prefer 32bpp fb for 24bpp pixmaps */ +#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \ + && (f & PreferConvert24to32)) + +/* Does the screen prefer 24bpp fb for 32bpp pixmaps */ +#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \ + && (f & PreferConvert32to24)) + +/* Can the screen handle 32bpp pixmaps for 24bpp fb */ +#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24)) + +/* Can the screen handle 24bpp pixmaps for 32bpp fb */ +#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32)) + +#ifndef GLOBAL_DEFAULT_DEPTH +#define GLOBAL_DEFAULT_DEPTH 24 +#endif + +Bool +xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp, + int depth24flags) +{ + int i; + DispPtr disp; + Pix24Flags pix24 = xf86Info.pixmap24; + Bool nomatch = FALSE; + + scrp->bitsPerPixel = -1; + scrp->depth = -1; + scrp->pixmap24 = Pix24DontCare; + scrp->bitsPerPixelFrom = X_DEFAULT; + scrp->depthFrom = X_DEFAULT; + + if (xf86FbBpp > 0) { + scrp->bitsPerPixel = xf86FbBpp; + scrp->bitsPerPixelFrom = X_CMDLINE; + } + + if (xf86Depth > 0) { + scrp->depth = xf86Depth; + scrp->depthFrom = X_CMDLINE; + } + + if (xf86FbBpp < 0 && xf86Depth < 0) { + if (scrp->confScreen->defaultfbbpp > 0) { + scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp; + scrp->bitsPerPixelFrom = X_CONFIG; + } + if (scrp->confScreen->defaultdepth > 0) { + scrp->depth = scrp->confScreen->defaultdepth; + scrp->depthFrom = X_CONFIG; + } + + if (scrp->confScreen->defaultfbbpp <= 0 && + scrp->confScreen->defaultdepth <= 0) { + /* + * Check for DefaultDepth and DefaultFbBpp options in the + * Device sections. + */ + int i; + GDevPtr device; + Bool found = FALSE; + + for (i = 0; i < scrp->numEntities; i++) { + device = xf86GetDevFromEntity(scrp->entityList[i], + scrp->entityInstanceList[i]); + if (device && device->options) { + if (xf86FindOption(device->options, "DefaultDepth")) { + scrp->depth = xf86SetIntOption(device->options, + "DefaultDepth", -1); + scrp->depthFrom = X_CONFIG; + found = TRUE; + } + if (xf86FindOption(device->options, "DefaultFbBpp")) { + scrp->bitsPerPixel = xf86SetIntOption(device->options, + "DefaultFbBpp", + -1); + scrp->bitsPerPixelFrom = X_CONFIG; + found = TRUE; + } + } + if (found) + break; + } + } + } + + /* If none of these is set, pick a default */ + if (scrp->bitsPerPixel < 0 && scrp->depth < 0) { + if (fbbpp > 0 || depth > 0) { + if (fbbpp > 0) + scrp->bitsPerPixel = fbbpp; + if (depth > 0) + scrp->depth = depth; + } else { + scrp->depth = GLOBAL_DEFAULT_DEPTH; + } + } + + /* If any are not given, determine a default for the others */ + + if (scrp->bitsPerPixel < 0) { + /* The depth must be set */ + if (scrp->depth > -1) { + if (scrp->depth == 1) + scrp->bitsPerPixel = 1; + else if (scrp->depth <= 4) + scrp->bitsPerPixel = 4; + else if (scrp->depth <= 8) + scrp->bitsPerPixel = 8; + else if (scrp->depth <= 16) + scrp->bitsPerPixel = 16; + else if (scrp->depth <= 24) { + /* + * Figure out if a choice is possible based on the depth24 + * and pix24 flags. + */ + /* Check pix24 first */ + if (pix24 != Pix24DontCare) { + if (pix24 == Pix24Use32) { + if (DO_PIX32(depth24flags)) { + if (CHOOSE24FOR32(depth24flags)) + scrp->bitsPerPixel = 24; + else + scrp->bitsPerPixel = 32; + } else { + nomatch = TRUE; + } + } else if (pix24 == Pix24Use24) { + if (DO_PIX24(depth24flags)) { + if (CHOOSE32FOR24(depth24flags)) + scrp->bitsPerPixel = 32; + else + scrp->bitsPerPixel = 24; + } else { + nomatch = TRUE; + } + } + } else { + if (DO_PIX32(depth24flags)) { + if (CHOOSE24FOR32(depth24flags)) + scrp->bitsPerPixel = 24; + else + scrp->bitsPerPixel = 32; + } else if (DO_PIX24(depth24flags)) { + if (CHOOSE32FOR24(depth24flags)) + scrp->bitsPerPixel = 32; + else + scrp->bitsPerPixel = 24; + } + } + } else if (scrp->depth <= 32) + scrp->bitsPerPixel = 32; + else { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Specified depth (%d) is greater than 32\n", + scrp->depth); + return FALSE; + } + } else { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "xf86SetDepthBpp: internal error: depth and fbbpp" + " are both not set\n"); + return FALSE; + } + if (scrp->bitsPerPixel < 0) { + if (nomatch) + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Driver can't support depth 24 pixmap format (%d)\n", + PIX24TOBPP(pix24)); + else if ((depth24flags & (Support24bppFb | Support32bppFb)) == + NoDepth24Support) + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Driver can't support depth 24\n"); + else + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Can't find fbbpp for depth 24\n"); + return FALSE; + } + scrp->bitsPerPixelFrom = X_PROBED; + } + + if (scrp->depth <= 0) { + /* bitsPerPixel is already set */ + switch (scrp->bitsPerPixel) { + case 32: + scrp->depth = 24; + break; + default: + /* 1, 4, 8, 16 and 24 */ + scrp->depth = scrp->bitsPerPixel; + break; + } + scrp->depthFrom = X_PROBED; + } + + /* Sanity checks */ + if (scrp->depth < 1 || scrp->depth > 32) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Specified depth (%d) is not in the range 1-32\n", + scrp->depth); + return FALSE; + } + switch (scrp->bitsPerPixel) { + case 1: + case 4: + case 8: + case 16: + case 24: + case 32: + break; + default: + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Specified fbbpp (%d) is not a permitted value\n", + scrp->bitsPerPixel); + return FALSE; + } + if (scrp->depth > scrp->bitsPerPixel) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Specified depth (%d) is greater than the fbbpp (%d)\n", + scrp->depth, scrp->bitsPerPixel); + return FALSE; + } + + /* set scrp->pixmap24 if the driver isn't flexible */ + if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) { + scrp->pixmap24 = Pix24Use24; + } + if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) { + scrp->pixmap24 = Pix24Use32; + } + + /* + * Find the Display subsection matching the depth/fbbpp and initialise + * scrp->display with it. + */ + for (i = 0, disp = scrp->confScreen->displays; + i < scrp->confScreen->numdisplays; i++, disp++) { + if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel) + || (disp->depth == scrp->depth && disp->fbbpp <= 0) + || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) { + scrp->display = disp; + break; + } + } + + /* + * If an exact match can't be found, see if there is one with no + * depth or fbbpp specified. + */ + if (i == scrp->confScreen->numdisplays) { + for (i = 0, disp = scrp->confScreen->displays; + i < scrp->confScreen->numdisplays; i++, disp++) { + if (disp->depth <= 0 && disp->fbbpp <= 0) { + scrp->display = disp; + break; + } + } + } + + /* + * If all else fails, create a default one. + */ + if (i == scrp->confScreen->numdisplays) { + scrp->confScreen->numdisplays++; + scrp->confScreen->displays = + xnfrealloc(scrp->confScreen->displays, + scrp->confScreen->numdisplays * sizeof(DispRec)); + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "Creating default Display subsection in Screen section\n" + "\t\"%s\" for depth/fbbpp %d/%d\n", + scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel); + memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec)); + scrp->confScreen->displays[i].blackColour.red = -1; + scrp->confScreen->displays[i].blackColour.green = -1; + scrp->confScreen->displays[i].blackColour.blue = -1; + scrp->confScreen->displays[i].whiteColour.red = -1; + scrp->confScreen->displays[i].whiteColour.green = -1; + scrp->confScreen->displays[i].whiteColour.blue = -1; + scrp->confScreen->displays[i].defaultVisual = -1; + scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *)); + scrp->confScreen->displays[i].modes[0] = NULL; + scrp->confScreen->displays[i].depth = depth; + scrp->confScreen->displays[i].fbbpp = fbbpp; + scrp->display = &scrp->confScreen->displays[i]; + } + + /* + * Setup defaults for the display-wide attributes the framebuffer will + * need. These defaults should eventually be set globally, and not + * dependent on the screens. + */ + scrp->imageByteOrder = IMAGE_BYTE_ORDER; + scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + if (scrp->depth < 8) { + /* Planar modes need these settings */ + scrp->bitmapScanlineUnit = 8; + scrp->bitmapBitOrder = MSBFirst; + } else { + scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + scrp->bitmapBitOrder = BITMAP_BIT_ORDER; + } + + /* + * If an unusual depth is required, add it to scrp->formats. The formats + * for the common depths are handled globally in InitOutput + */ + switch (scrp->depth) { + case 1: + case 4: + case 8: + case 15: + case 16: + case 24: + /* Common depths. Nothing to do for them */ + break; + default: + if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Can't add pixmap format for depth %d\n", scrp->depth); + return FALSE; + } + } + + /* Initialise the framebuffer format for this screen */ + scrp->fbFormat.depth = scrp->depth; + scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel; + scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD; + + return TRUE; +} + +/* + * Print out the selected depth and bpp. + */ +void +xf86PrintDepthBpp(ScrnInfoPtr scrp) +{ + xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth); + xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel); +} + +/* + * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths + * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits. + */ +Bool +xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask) +{ + MessageType weightFrom = X_DEFAULT; + + scrp->weight.red = 0; + scrp->weight.green = 0; + scrp->weight.blue = 0; + + if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) { + scrp->weight = xf86Weight; + weightFrom = X_CMDLINE; + } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0 + && scrp->display->weight.blue > 0) { + scrp->weight = scrp->display->weight; + weightFrom = X_CONFIG; + } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) { + scrp->weight = weight; + } else { + switch (scrp->depth) { + case 1: + case 4: + case 8: + scrp->weight.red = scrp->weight.green = + scrp->weight.blue = scrp->rgbBits; + break; + case 15: + scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5; + break; + case 16: + scrp->weight.red = scrp->weight.blue = 5; + scrp->weight.green = 6; + break; + case 18: + scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6; + break; + case 24: + scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8; + break; + case 30: + scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10; + break; + } + } + + if (scrp->weight.red) + xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n", + (int)scrp->weight.red, (int)scrp->weight.green, + (int)scrp->weight.blue); + + if (scrp->depth > MAX_PSEUDO_DEPTH && + (scrp->depth != scrp->weight.red + scrp->weight.green + + scrp->weight.blue)) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Weight given (%d%d%d) is inconsistent with the " + "depth (%d)\n", + (int)scrp->weight.red, (int)scrp->weight.green, + (int)scrp->weight.blue, scrp->depth); + return FALSE; + } + if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) { + /* + * XXX Does this even mean anything for TrueColor visuals? + * If not, we shouldn't even be setting it here. However, this + * matches the behaviour of 3.x versions of XFree86. + */ + scrp->rgbBits = scrp->weight.red; + if (scrp->weight.green > scrp->rgbBits) + scrp->rgbBits = scrp->weight.green; + if (scrp->weight.blue > scrp->rgbBits) + scrp->rgbBits = scrp->weight.blue; + } + + /* Set the mask and offsets */ + if (mask.red == 0 || mask.green == 0 || mask.blue == 0) { + /* Default to a setting common to PC hardware */ + scrp->offset.red = scrp->weight.green + scrp->weight.blue; + scrp->offset.green = scrp->weight.blue; + scrp->offset.blue = 0; + scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red; + scrp->mask.green = ((1 << scrp->weight.green) - 1) + << scrp->offset.green; + scrp->mask.blue = (1 << scrp->weight.blue) - 1; + } else { + /* Initialise to the values passed */ + scrp->mask.red = mask.red; + scrp->mask.green = mask.green; + scrp->mask.blue = mask.blue; + scrp->offset.red = ffs(mask.red); + scrp->offset.green = ffs(mask.green); + scrp->offset.blue = ffs(mask.blue); + } + return TRUE; +} + +Bool +xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual) +{ + MessageType visualFrom = X_DEFAULT; + + if (defaultColorVisualClass >= 0) { + scrp->defaultVisual = defaultColorVisualClass; + visualFrom = X_CMDLINE; + } else if (scrp->display->defaultVisual >= 0) { + scrp->defaultVisual = scrp->display->defaultVisual; + visualFrom = X_CONFIG; + } else if (visual >= 0) { + scrp->defaultVisual = visual; + } else { + if (scrp->depth == 1) + scrp->defaultVisual = StaticGray; + else if (scrp->depth == 4) + scrp->defaultVisual = StaticColor; + else if (scrp->depth <= MAX_PSEUDO_DEPTH) + scrp->defaultVisual = PseudoColor; + else + scrp->defaultVisual = TrueColor; + } + switch (scrp->defaultVisual) { + case StaticGray: + case GrayScale: + case StaticColor: + case PseudoColor: + case TrueColor: + case DirectColor: + xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n", + xf86VisualNames[scrp->defaultVisual]); + return TRUE; + default: + + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Invalid default visual class (%d)\n", scrp->defaultVisual); + return FALSE; + } +} + +#define TEST_GAMMA(g) \ + (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO + +#define SET_GAMMA(g) \ + (g) > GAMMA_ZERO ? (g) : 1.0 + +Bool +xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma) +{ + MessageType from = X_DEFAULT; +#if 0 + xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC); +#endif + if (TEST_GAMMA(xf86Gamma)) { + from = X_CMDLINE; + scrp->gamma.red = SET_GAMMA(xf86Gamma.red); + scrp->gamma.green = SET_GAMMA(xf86Gamma.green); + scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue); + } else if (TEST_GAMMA(scrp->monitor->gamma)) { + from = X_CONFIG; + scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red); + scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green); + scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue); +#if 0 + } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) { + from = X_PROBED; + scrp->gamma.red = SET_GAMMA(DDC->features.gamma); + scrp->gamma.green = SET_GAMMA(DDC->features.gamma); + scrp->gamma.blue = SET_GAMMA(DDC->features.gamma); + /* EDID structure version 2 gives optional seperate red, green & blue gamma values + * in bytes 0x57-0x59 */ +#endif + } else if (TEST_GAMMA(gamma)) { + scrp->gamma.red = SET_GAMMA(gamma.red); + scrp->gamma.green = SET_GAMMA(gamma.green); + scrp->gamma.blue = SET_GAMMA(gamma.blue); + } else { + scrp->gamma.red = 1.0; + scrp->gamma.green = 1.0; + scrp->gamma.blue = 1.0; + } + /* Pretend we succeeded if we support better a gamma system. + * This avoids a confusing message. + */ + if (xf86_crtc_supports_gamma(scrp)) + return TRUE; + xf86DrvMsg(scrp->scrnIndex, from, + "Using gamma correction (%.1f, %.1f, %.1f)\n", + scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue); + + return TRUE; +} + +#undef TEST_GAMMA +#undef SET_GAMMA + + +/* + * Set the DPI from the command line option. XXX should allow it to be + * calculated from the widthmm/heightmm values. + */ + +#undef MMPERINCH +#define MMPERINCH 25.4 + +void +xf86SetDpi(ScrnInfoPtr pScrn, int x, int y) +{ + MessageType from = X_DEFAULT; + xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC); + int ddcWidthmm, ddcHeightmm; + int widthErr, heightErr; + + /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */ + pScrn->widthmm = pScrn->monitor->widthmm; + pScrn->heightmm = pScrn->monitor->heightmm; + + if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) { + /* DDC gives display size in mm for individual modes, + * but cm for monitor + */ + ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */ + ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */ + } else { + ddcWidthmm = ddcHeightmm = 0; + } + + if (monitorResolution > 0) { + pScrn->xDpi = monitorResolution; + pScrn->yDpi = monitorResolution; + from = X_CMDLINE; + } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) { + from = X_CONFIG; + if (pScrn->widthmm > 0) { + pScrn->xDpi = + (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm); + } + if (pScrn->heightmm > 0) { + pScrn->yDpi = + (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm); + } + if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) + pScrn->yDpi = pScrn->xDpi; + if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) + pScrn->xDpi = pScrn->yDpi; + xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", + pScrn->widthmm, pScrn->heightmm); + + /* Warn if config and probe disagree about display size */ + if ( ddcWidthmm && ddcHeightmm ) { + if (pScrn->widthmm > 0) { + widthErr = abs(ddcWidthmm - pScrn->widthmm); + } else { + widthErr = 0; + } + if (pScrn->heightmm > 0) { + heightErr = abs(ddcHeightmm - pScrn->heightmm); + } else { + heightErr = 0; + } + if (widthErr>10 || heightErr>10) { + /* Should include config file name for monitor here */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n", + ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm); + } + } + } else if ( ddcWidthmm && ddcHeightmm ) { + from = X_PROBED; + xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", + ddcWidthmm, ddcHeightmm ); + pScrn->widthmm = ddcWidthmm; + pScrn->heightmm = ddcHeightmm; + if (pScrn->widthmm > 0) { + pScrn->xDpi = + (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm); + } + if (pScrn->heightmm > 0) { + pScrn->yDpi = + (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm); + } + if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) + pScrn->yDpi = pScrn->xDpi; + if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) + pScrn->xDpi = pScrn->yDpi; + } else { + if (x > 0) + pScrn->xDpi = x; + else + pScrn->xDpi = DEFAULT_DPI; + if (y > 0) + pScrn->yDpi = y; + else + pScrn->yDpi = DEFAULT_DPI; + } + xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n", + pScrn->xDpi, pScrn->yDpi); +} + +#undef MMPERINCH + + +void +xf86SetBlackWhitePixels(ScreenPtr pScreen) +{ + if (xf86FlipPixels) { + pScreen->whitePixel = 0; + pScreen->blackPixel = 1; + } else { + pScreen->whitePixel = 1; + pScreen->blackPixel = 0; + } +} + +/* + * xf86SetRootClip -- + * Enable or disable rendering to the screen by + * setting the root clip list and revalidating + * all of the windows + */ + +static void +xf86SetRootClip (ScreenPtr pScreen, Bool enable) +{ + WindowPtr pWin = pScreen->root; + WindowPtr pChild; + Bool WasViewable = (Bool)(pWin->viewable); + Bool anyMarked = FALSE; + WindowPtr pLayerWin; + BoxRec box; + + if (WasViewable) + { + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) + { + (void) (*pScreen->MarkOverlappedWindows)(pChild, + pChild, + &pLayerWin); + } + (*pScreen->MarkWindow) (pWin); + anyMarked = TRUE; + if (pWin->valdata) + { + if (HasBorder (pWin)) + { + RegionPtr borderVisible; + + borderVisible = RegionCreate(NullBox, 1); + RegionSubtract(borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + } + pWin->valdata->before.resized = TRUE; + } + } + + /* + * Use REGION_BREAK to avoid optimizations in ValidateTree + * that assume the root borderClip can't change well, normally + * it doesn't...) + */ + if (enable) + { + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + RegionInit(&pWin->winSize, &box, 1); + RegionInit(&pWin->borderSize, &box, 1); + if (WasViewable) + RegionReset(&pWin->borderClip, &box); + pWin->drawable.width = pScreen->width; + pWin->drawable.height = pScreen->height; + RegionBreak(&pWin->clipList); + } + else + { + RegionEmpty(&pWin->borderClip); + RegionBreak(&pWin->clipList); + } + + ResizeChildrenWinSize (pWin, 0, 0, 0, 0); + + if (WasViewable) + { + if (pWin->firstChild) + { + anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, + pWin->firstChild, + (WindowPtr *)NULL); + } + else + { + (*pScreen->MarkWindow) (pWin); + anyMarked = TRUE; + } + + + if (anyMarked) + (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); + } + + if (WasViewable) + { + if (anyMarked) + (*pScreen->HandleExposures)(pWin); + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); + } + if (pWin->realized) + WindowsRestructured (); + FlushAllOutput (); +} + +/* + * Function to enable/disable access to the frame buffer + * + * This is used when VT switching and when entering/leaving DGA direct mode. + * + * This has been rewritten again to eliminate the saved pixmap. The + * devPrivate field in the screen pixmap is set to NULL to catch code + * accidentally referencing the frame buffer while the X server is not + * supposed to touch it. + * + * Here, we exchange the pixmap private data, rather than the pixmaps + * themselves to avoid having to find and change any references to the screen + * pixmap such as GC's, window privates etc. This also means that this code + * does not need to know exactly how the pixmap pixels are accessed. Further, + * this exchange is >not< done through the screen's ModifyPixmapHeader() + * vector. This means the called frame buffer code layers can determine + * whether they are switched in or out by keeping track of the root pixmap's + * private data, and therefore don't need to access pScrnInfo->vtSema. + */ +void +xf86EnableDisableFBAccess(int scrnIndex, Bool enable) +{ + ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex]; + ScreenPtr pScreen = pScrnInfo->pScreen; + PixmapPtr pspix; + + pspix = (*pScreen->GetScreenPixmap) (pScreen); + if (enable) + { + /* + * Restore all of the clip lists on the screen + */ + if (!xf86Resetting) + xf86SetRootClip (pScreen, TRUE); + + } + else + { + /* + * Empty all of the clip lists on the screen + */ + xf86SetRootClip (pScreen, FALSE); + } +} + +/* Print driver messages in the standard format */ + +#undef PREFIX_SIZE +#define PREFIX_SIZE 14 + +void +xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, + va_list args) +{ + char *tmpFormat; + + /* Prefix the scrnIndex name to the format string. */ + if (scrnIndex >= 0 && scrnIndex < xf86NumScreens && + xf86Screens[scrnIndex]->name) { + tmpFormat = malloc(strlen(format) + + strlen(xf86Screens[scrnIndex]->name) + + PREFIX_SIZE + 1); + if (!tmpFormat) + return; + + snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ", + xf86Screens[scrnIndex]->name, scrnIndex); + + strcat(tmpFormat, format); + LogVMessageVerb(type, verb, tmpFormat, args); + free(tmpFormat); + } else + LogVMessageVerb(type, verb, format, args); +} +#undef PREFIX_SIZE + +/* Print driver messages, with verbose level specified directly */ +void +xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, + ...) +{ + va_list ap; + + va_start(ap, format); + xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap); + va_end(ap); +} + +/* Print driver messages, with verbose level of 1 (default) */ +void +xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap); + va_end(ap); +} + +/* Print input driver messages in the standard format of + : : */ +void +xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format, + va_list args) +{ + char *msg; + + if (asprintf(&msg, "%s: %s: %s", dev->drv->driverName, dev->name, format) + == -1) { + LogVMessageVerb(type, verb, "%s", args); + } else { + LogVMessageVerb(type, verb, msg, args); + free(msg); + } +} + +/* Print input driver message, with verbose level specified directly */ +void +xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format, + ...) +{ + va_list ap; + + va_start(ap, format); + xf86VIDrvMsgVerb(dev, type, verb, format, ap); + va_end(ap); +} + +/* Print input driver messages, with verbose level of 1 (default) */ +void +xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + xf86VIDrvMsgVerb(dev, type, 1, format, ap); + va_end(ap); +} + + +/* Print non-driver messages with verbose level specified directly */ +void +xf86MsgVerb(MessageType type, int verb, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + LogVMessageVerb(type, verb, format, ap); + va_end(ap); +} + +/* Print non-driver messages with verbose level of 1 (default) */ +void +xf86Msg(MessageType type, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + LogVMessageVerb(type, 1, format, ap); + va_end(ap); +} + +/* Just like ErrorF, but with the verbose level checked */ +void +xf86ErrorFVerb(int verb, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + if (xf86Verbose >= verb || xf86LogVerbose >= verb) + LogVWrite(verb, format, ap); + va_end(ap); +} + +/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */ +void +xf86ErrorF(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + if (xf86Verbose >= 1 || xf86LogVerbose >= 1) + LogVWrite(1, format, ap); + va_end(ap); +} + + +void +xf86LogInit(void) +{ + char *lf = NULL; + +#define LOGSUFFIX ".log" +#define LOGOLDSUFFIX ".old" + + /* Get the log file name */ + if (xf86LogFileFrom == X_DEFAULT) { + /* Append the display number and ".log" */ + if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1) + FatalError("Cannot allocate space for the log file name\n"); + xf86LogFile = lf; + } + + xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX); + xf86LogFileWasOpened = TRUE; + + xf86SetVerbosity(xf86Verbose); + xf86SetLogVerbosity(xf86LogVerbose); + +#undef LOGSUFFIX +#undef LOGOLDSUFFIX + + free(lf); +} + +void +xf86CloseLog(void) +{ + LogClose(); +} + + +/* + * Drivers can use these for using their own SymTabRecs. + */ + +const char * +xf86TokenToString(SymTabPtr table, int token) +{ + int i; + + for (i = 0; table[i].token >= 0 && table[i].token != token; i++) + ; + + if (table[i].token < 0) + return NULL; + else + return table[i].name; +} + +int +xf86StringToToken(SymTabPtr table, const char *string) +{ + int i; + + if (string == NULL) + return -1; + + for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++) + ; + + return table[i].token; +} + +/* + * helper to display the clocks found on a card + */ +void +xf86ShowClocks(ScrnInfoPtr scrp, MessageType from) +{ + int j; + + xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:"); + for (j=0; j < scrp->numClocks; j++) { + if ((j % 4) == 0) { + xf86ErrorF("\n"); + xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:"); + } + xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0); + } + xf86ErrorF("\n"); +} + + +/* + * This prints out the driver identify message, including the names of + * the supported chipsets. + * + * XXX This makes assumptions about the line width, etc. Maybe we could + * use a more general "pretty print" function for messages. + */ +void +xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips) +{ + int len, i; + + len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2; + xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg); + for (i = 0; chips[i].name != NULL; i++) { + if (i != 0) { + xf86ErrorF(","); + len++; + } + if (len + 2 + strlen(chips[i].name) < 78) { + xf86ErrorF(" "); + len++; + } else { + xf86ErrorF("\n\t"); + len = 8; + } + xf86ErrorF("%s", chips[i].name); + len += strlen(chips[i].name); + } + xf86ErrorF("\n"); +} + + +int +xf86MatchDevice(const char *drivername, GDevPtr **sectlist) +{ + GDevPtr gdp, *pgdp = NULL; + confScreenPtr screensecptr; + int i,j; + + if (sectlist) + *sectlist = NULL; + + /* + * This can happen when running Xorg -showopts and a module like ati + * or vmware tries to load its submodules when xf86ConfigLayout is empty + */ + if (!xf86ConfigLayout.screens) + return 0; + + /* + * This is a very important function that matches the device sections + * as they show up in the config file with the drivers that the server + * loads at run time. + * + * ChipProbe can call + * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist) + * with its driver name. The function allocates an array of GDevPtr and + * returns this via sectlist and returns the number of elements in + * this list as return value. 0 means none found, -1 means fatal error. + * + * It can figure out which of the Device sections to use for which card + * (using things like the Card statement, etc). For single headed servers + * there will of course be just one such Device section. + */ + i = 0; + + /* + * first we need to loop over all the Screens sections to get to all + * 'active' device sections + */ + for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) { + screensecptr = xf86ConfigLayout.screens[j].screen; + if ((screensecptr->device->driver != NULL) + && (xf86NameCmp( screensecptr->device->driver,drivername) == 0) + && (! screensecptr->device->claimed)) { + /* + * we have a matching driver that wasn't claimed, yet + */ + pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); + pgdp[i++] = screensecptr->device; + } + } + + /* Then handle the inactive devices */ + j = 0; + while (xf86ConfigLayout.inactives[j].identifier) { + gdp = &xf86ConfigLayout.inactives[j]; + if (gdp->driver && !gdp->claimed && + !xf86NameCmp(gdp->driver,drivername)) { + /* we have a matching driver that wasn't claimed yet */ + pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); + pgdp[i++] = gdp; + } + j++; + } + + /* + * make the array NULL terminated and return its address + */ + if (i) + pgdp[i] = NULL; + + if (sectlist) + *sectlist = pgdp; + else + free(pgdp); + return i; +} + +/* + * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ... + */ +void +xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int), + void (*ProtectRegs)(ScrnInfoPtr, Bool), + void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg, + int maskval, int knownclkindex, int knownclkvalue) +{ + register int status = vertsyncreg; + unsigned long i, cnt, rcnt, sync; + + /* First save registers that get written on */ + (*ClockFunc)(pScrn, CLK_REG_SAVE); + + if (num > MAXCLOCKS) + num = MAXCLOCKS; + + for (i = 0; i < num; i++) + { + if (ProtectRegs) + (*ProtectRegs)(pScrn, TRUE); + if (!(*ClockFunc)(pScrn, i)) + { + pScrn->clock[i] = -1; + continue; + } + if (ProtectRegs) + (*ProtectRegs)(pScrn, FALSE); + if (BlankScreen) + (*BlankScreen)(pScrn, FALSE); + + usleep(50000); /* let VCO stabilise */ + + cnt = 0; + sync = 200000; + + while ((inb(status) & maskval) == 0x00) + if (sync-- == 0) goto finish; + /* Something appears to be happening, so reset sync count */ + sync = 200000; + while ((inb(status) & maskval) == maskval) + if (sync-- == 0) goto finish; + /* Something appears to be happening, so reset sync count */ + sync = 200000; + while ((inb(status) & maskval) == 0x00) + if (sync-- == 0) goto finish; + + for (rcnt = 0; rcnt < 5; rcnt++) + { + while (!(inb(status) & maskval)) + cnt++; + while ((inb(status) & maskval)) + cnt++; + } + +finish: + pScrn->clock[i] = cnt ? cnt : -1; + if (BlankScreen) + (*BlankScreen)(pScrn, TRUE); + } + + for (i = 0; i < num; i++) + { + if (i != knownclkindex) + { + if (pScrn->clock[i] == -1) + { + pScrn->clock[i] = 0; + } + else + { + pScrn->clock[i] = (int)(0.5 + + (((float)knownclkvalue) * pScrn->clock[knownclkindex]) / + (pScrn->clock[i])); + /* Round to nearest 10KHz */ + pScrn->clock[i] += 5; + pScrn->clock[i] /= 10; + pScrn->clock[i] *= 10; + } + } + } + + pScrn->clock[knownclkindex] = knownclkvalue; + pScrn->numClocks = num; + + /* Restore registers that were written on */ + (*ClockFunc)(pScrn, CLK_REG_RESTORE); +} + +const char * +xf86GetVisualName(int visual) +{ + if (visual < 0 || visual > DirectColor) + return NULL; + + return xf86VisualNames[visual]; +} + + +int +xf86GetVerbosity(void) +{ + return max(xf86Verbose, xf86LogVerbose); +} + +Pix24Flags +xf86GetPix24(void) +{ + return xf86Info.pixmap24; +} + + +int +xf86GetDepth(void) +{ + return xf86Depth; +} + + +rgb +xf86GetWeight(void) +{ + return xf86Weight; +} + + +Gamma +xf86GetGamma(void) +{ + return xf86Gamma; +} + + +Bool +xf86GetFlipPixels(void) +{ + return xf86FlipPixels; +} + + +const char * +xf86GetServerName(void) +{ + return xf86ServerName; +} + + +Bool +xf86ServerIsExiting(void) +{ + return (dispatchException & DE_TERMINATE) == DE_TERMINATE; +} + + +Bool +xf86ServerIsResetting(void) +{ + return xf86Resetting; +} + + +Bool +xf86ServerIsInitialising(void) +{ + return xf86Initialising; +} + + +Bool +xf86ServerIsOnlyDetecting(void) +{ + return xf86DoConfigure; +} + + +Bool +xf86CaughtSignal(void) +{ + return xf86Info.caughtSignal; +} + + +Bool +xf86GetVidModeAllowNonLocal(void) +{ + return xf86Info.vidModeAllowNonLocal; +} + + +Bool +xf86GetVidModeEnabled(void) +{ + return xf86Info.vidModeEnabled; +} + +Bool +xf86GetModInDevAllowNonLocal(void) +{ + return xf86Info.miscModInDevAllowNonLocal; +} + + +Bool +xf86GetModInDevEnabled(void) +{ + return xf86Info.miscModInDevEnabled; +} + + +Bool +xf86GetAllowMouseOpenFail(void) +{ + return xf86Info.allowMouseOpenFail; +} + + +Bool +xf86IsPc98(void) +{ +#if SUPPORT_PC98 + return xf86Info.pc98; +#else + return FALSE; +#endif +} + +void +xf86DisableRandR(void) +{ + xf86Info.disableRandR = TRUE; + xf86Info.randRFrom = X_PROBED; +} + +CARD32 +xf86GetModuleVersion(pointer module) +{ + return (CARD32)LoaderGetModuleVersion(module); +} + +pointer +xf86LoadDrvSubModule(DriverPtr drv, const char *name) +{ + pointer ret; + int errmaj = 0, errmin = 0; + + ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL, + &errmaj, &errmin); + if (!ret) + LoaderErrorMsg(NULL, name, errmaj, errmin); + return ret; +} + +pointer +xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name) +{ + pointer ret; + int errmaj = 0, errmin = 0; + + ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL, + &errmaj, &errmin); + if (!ret) + LoaderErrorMsg(pScrn->name, name, errmaj, errmin); + return ret; +} + +/* + * xf86LoadOneModule loads a single module. + */ +pointer +xf86LoadOneModule(char *name, pointer opt) +{ + int errmaj, errmin; + char *Name; + pointer mod; + + if (!name) + return NULL; + + /* Normalise the module name */ + Name = xf86NormalizeName(name); + + /* Skip empty names */ + if (Name == NULL) + return NULL; + if (*Name == '\0') { + free(Name); + return NULL; + } + + mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin); + if (!mod) + LoaderErrorMsg(NULL, Name, errmaj, errmin); + free(Name); + return mod; +} + +void +xf86UnloadSubModule(pointer mod) +{ + /* + * This is disabled for now. The loader isn't smart enough yet to undo + * relocations. + */ +#if 0 + UnloadSubModule(mod); +#endif +} + +Bool +xf86LoaderCheckSymbol(const char *name) +{ + return LoaderSymbol(name) != NULL; +} + +typedef enum { + OPTION_BACKING_STORE +} BSOpts; + +static const OptionInfoRec BSOptions[] = { + { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +void +xf86SetBackingStore(ScreenPtr pScreen) +{ + Bool useBS = FALSE; + MessageType from = X_DEFAULT; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + OptionInfoPtr options; + + options = xnfalloc(sizeof(BSOptions)); + (void)memcpy(options, BSOptions, sizeof(BSOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); + + /* check for commandline option here */ + if (xf86bsEnableFlag) { + from = X_CMDLINE; + useBS = TRUE; + } else if (xf86bsDisableFlag) { + from = X_CMDLINE; + useBS = FALSE; + } else { + if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS)) + from = X_CONFIG; + } + free(options); + pScreen->backingStoreSupport = useBS ? Always : NotUseful; + if (serverGeneration == 1) + xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n", + useBS ? "enabled" : "disabled"); +} + + +typedef enum { + OPTION_SILKEN_MOUSE +} SMOpts; + +static const OptionInfoRec SMOptions[] = { + { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +void +xf86SetSilkenMouse (ScreenPtr pScreen) +{ + Bool useSM = TRUE; + MessageType from = X_DEFAULT; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + OptionInfoPtr options; + + options = xnfalloc(sizeof(SMOptions)); + (void)memcpy(options, SMOptions, sizeof(SMOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); + + /* check for commandline option here */ + /* disable if screen shares resources */ + /* TODO VGA arb disable silken mouse */ + if (xf86silkenMouseDisableFlag) { + from = X_CMDLINE; + useSM = FALSE; + } else { + if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM)) + from = X_CONFIG; + } + free(options); + /* + * XXX quick hack to report correctly for OSs that can't do SilkenMouse + * yet. Should handle this differently so that alternate async methods + * work correctly with this too. + */ + pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported(); + if (serverGeneration == 1) + xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n", + pScrn->silkenMouse ? "enabled" : "disabled"); +} + +/* Wrote this function for the PM2 Xv driver, preliminary. */ + +pointer +xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name, + char **adaptor_name, pointer *adaptor_options) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + confXvAdaptorPtr adaptor; + int i; + + if (adaptor_index >= pScrn->confScreen->numxvadaptors) { + if (adaptor_name) *adaptor_name = NULL; + if (adaptor_options) *adaptor_options = NULL; + return NULL; + } + + adaptor = &pScrn->confScreen->xvadaptors[adaptor_index]; + if (adaptor_name) *adaptor_name = adaptor->identifier; + if (adaptor_options) *adaptor_options = adaptor->options; + + for (i = 0; i < adaptor->numports; i++) + if (!xf86NameCmp(adaptor->ports[i].identifier, port_name)) + return adaptor->ports[i].options; + + return NULL; +} + +/* Rather than duplicate loader's get OS function, just include it directly */ +#define LoaderGetOS xf86GetOS +#include "loader/os.c" + +static void +xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init, + EntityProc enter, EntityProc leave, pointer private) +{ + ScrnInfoPtr pScrn; + + if ((pScrn = xf86FindScreenForEntity(pEnt->index))) + xf86RemoveEntityFromScreen(pScrn,pEnt->index); + xf86SetEntityFuncs(pEnt->index,init,enter,leave,private); +} + +ScrnInfoPtr +xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex, + EntityProc init, EntityProc enter, EntityProc leave, + pointer private) +{ + EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex); + if (!pEnt) return pScrn; + + if (!(pEnt->location.type == BUS_NONE)) { + free(pEnt); + return pScrn; + } + + if (!pEnt->active) { + xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private); + free(pEnt); + return pScrn; + } + + if (!pScrn) + pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag); + xf86AddEntityToScreen(pScrn,entityIndex); + + xf86SetEntityFuncs(entityIndex,init,enter,leave,private); + + return pScrn; +} + +Bool +xf86IsScreenPrimary(int scrnIndex) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + int i; + + for (i=0 ; i < pScrn->numEntities; i++) { + if (xf86IsEntityPrimary(i)) + return TRUE; + } + return FALSE; +} + +int +xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type, + int format, unsigned long len, pointer value ) +{ + RootWinPropPtr pNewProp = NULL, pRegProp; + int i; + Bool existing = FALSE; + + DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n", + ScrnIndex, property, type, format, len, value); + + if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) { + return BadMatch; + } + + if (xf86RegisteredPropertiesTable && + xf86RegisteredPropertiesTable[ScrnIndex]) { + for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex]; + pNewProp; pNewProp = pNewProp->next) { + if (strcmp(pNewProp->name, NameForAtom(property)) == 0) + break; + } + } + + if (!pNewProp) { + if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) { + return BadAlloc; + } + /* + * We will put this property at the end of the list so that + * the changes are made in the order they were requested. + */ + pNewProp->next = NULL; + } else { + free(pNewProp->name); + existing = TRUE; + } + + pNewProp->name = xnfstrdup(NameForAtom(property)); + pNewProp->type = type; + pNewProp->format = format; + pNewProp->size = len; + pNewProp->data = value; + + DebugF("new property filled\n"); + + if (NULL==xf86RegisteredPropertiesTable) { + DebugF("creating xf86RegisteredPropertiesTable[] size %d\n", + xf86NumScreens); + if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) { + return BadAlloc; + } + for (i=0; inext != NULL) { + DebugF("- next %p\n", (void *)pRegProp); + pRegProp = pRegProp->next; + } + pRegProp->next = pNewProp; + } + } + DebugF("xf86RegisterRootWindowProperty succeeded\n"); + return Success; +} + +Bool +xf86IsUnblank(int mode) +{ + switch(mode) { + case SCREEN_SAVER_OFF: + case SCREEN_SAVER_FORCER: + return TRUE; + case SCREEN_SAVER_ON: + case SCREEN_SAVER_CYCLE: + return FALSE; + default: + xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode); + return TRUE; + } +} + +void +xf86MotionHistoryAllocate(InputInfoPtr pInfo) +{ + AllocateMotionHistory(pInfo->dev); +} diff --git a/xorg-server/hw/xfree86/common/xf86Module.h b/xorg-server/hw/xfree86/common/xf86Module.h index 49a98bd05..581047dcf 100644 --- a/xorg-server/hw/xfree86/common/xf86Module.h +++ b/xorg-server/hw/xfree86/common/xf86Module.h @@ -82,7 +82,7 @@ typedef enum { * mask is 0xFFFF0000. */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) -#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(9, 0) +#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(10, 0) #define ABI_XINPUT_VERSION SET_ABI_VERSION(12, 2) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(5, 0) #define ABI_FONT_VERSION SET_ABI_VERSION(0, 6) diff --git a/xorg-server/hw/xfree86/common/xf86sbusBus.c b/xorg-server/hw/xfree86/common/xf86sbusBus.c index c0de88dda..181c6ab00 100644 --- a/xorg-server/hw/xfree86/common/xf86sbusBus.c +++ b/xorg-server/hw/xfree86/common/xf86sbusBus.c @@ -1,714 +1,714 @@ -/* - * SBUS bus-specific code. - * - * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) - * - * 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 - * JAKUB JELINEK 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. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include "os.h" -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86_OSlib.h" -#include "xf86cmap.h" - -#include "xf86Bus.h" - -#include "xf86sbusBus.h" -#include "xf86Sbus.h" - -Bool sbusSlotClaimed = FALSE; - -static int xf86nSbusInfo; - -static void -CheckSbusDevice(const char *device, int fbNum) -{ - int fd, i; - struct fbgattr fbattr; - sbusDevicePtr psdp; - - fd = open(device, O_RDONLY, 0); - if (fd < 0) - return; - memset(&fbattr, 0, sizeof(fbattr)); - if (ioctl(fd, FBIOGATTR, &fbattr) < 0) { - if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) { - close(fd); - return; - } - } - close(fd); - for (i = 0; sbusDeviceTable[i].devId; i++) - if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type) - break; - if (! sbusDeviceTable[i].devId) - return; - xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1)); - xf86SbusInfo[xf86nSbusInfo] = NULL; - xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1); - psdp->devId = sbusDeviceTable[i].devId; - psdp->fbNum = fbNum; - psdp->device = xnfstrdup(device); - psdp->width = fbattr.fbtype.fb_width; - psdp->height = fbattr.fbtype.fb_height; - psdp->fd = -1; -} - -void -xf86SbusProbe(void) -{ - int i, useProm = 0; - char fbDevName[32]; - sbusDevicePtr psdp, *psdpp; - - xf86SbusInfo = malloc(sizeof(psdp)); - *xf86SbusInfo = NULL; - for (i = 0; i < 32; i++) { - sprintf(fbDevName, "/dev/fb%d", i); - CheckSbusDevice(fbDevName, i); - } - if (sparcPromInit() >= 0) { - useProm = 1; - sparcPromAssignNodes(); - } - for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) { - for (i = 0; sbusDeviceTable[i].devId; i++) - if (sbusDeviceTable[i].devId == psdp->devId) - psdp->descr = sbusDeviceTable[i].descr; - /* - * If we can use PROM information and found the PROM node for this - * device, we can tell more about the card. - */ - if (useProm && psdp->node.node) { - char *prop, *promPath; - int len, chiprev, vmsize; - - switch (psdp->devId) { - case SBUS_DEVICE_MGX: - prop = sparcPromGetProperty(&psdp->node, "fb_size", &len); - if (prop && len == 4 && *(int *)prop == 0x400000) - psdp->descr = "Quantum 3D MGXplus with 4M VRAM"; - break; - case SBUS_DEVICE_CG6: - chiprev = 0; - vmsize = 0; - prop = sparcPromGetProperty(&psdp->node, "chiprev", &len); - if (prop && len == 4) - chiprev = *(int *)prop; - prop = sparcPromGetProperty(&psdp->node, "vmsize", &len); - if (prop && len == 4) - vmsize = *(int *)prop; - switch (chiprev) { - case 1: - case 2: - case 3: - case 4: - psdp->descr = "Sun Double width GX"; break; - case 5: - case 6: - case 7: - case 8: - case 9: - psdp->descr = "Sun Single width GX"; break; - case 11: - switch (vmsize) { - case 2: - psdp->descr = "Sun Turbo GX with 1M VSIMM"; break; - case 4: - psdp->descr = "Sun Turbo GX Plus"; break; - default: - psdp->descr = "Sun Turbo GX"; break; - } - } - break; - case SBUS_DEVICE_CG14: - prop = sparcPromGetProperty(&psdp->node, "reg", &len); - vmsize = 0; - if (prop && !(len % 12) && len > 0) - vmsize = *(int *)(prop + len - 4); - switch (vmsize) { - case 0x400000: - psdp->descr = "Sun SX with 4M VSIMM"; break; - case 0x800000: - psdp->descr = "Sun SX with 8M VSIMM"; break; - } - break; - case SBUS_DEVICE_LEO: - prop = sparcPromGetProperty(&psdp->node, "model", &len); - if (prop && len > 0 && !strstr(prop, "501-2503")) - psdp->descr = "Sun Turbo ZX"; - break; - case SBUS_DEVICE_TCX: - if (sparcPromGetBool(&psdp->node, "tcx-8-bit")) - psdp->descr = "Sun TCX (8bit)"; - else - psdp->descr = "Sun TCX (S24)"; - break; - case SBUS_DEVICE_FFB: - prop = sparcPromGetProperty(&psdp->node, "name", &len); - chiprev = 0; - prop = sparcPromGetProperty(&psdp->node, "board_type", &len); - if (prop && len == 4) - chiprev = *(int *)prop; - if (strstr (prop, "afb")) { - if (chiprev == 3) - psdp->descr = "Sun|Elite3D-M6 Horizontal"; - } else { - switch (chiprev) { - case 0x08: - psdp->descr = "Sun FFB 67MHz Creator"; break; - case 0x0b: - psdp->descr = "Sun FFB 67MHz Creator 3D"; break; - case 0x1b: - psdp->descr = "Sun FFB 75MHz Creator 3D"; break; - case 0x20: - case 0x28: - psdp->descr = "Sun FFB2 Vertical Creator"; break; - case 0x23: - case 0x2b: - psdp->descr = "Sun FFB2 Vertical Creator 3D"; break; - case 0x30: - psdp->descr = "Sun FFB2+ Vertical Creator"; break; - case 0x33: - psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break; - case 0x40: - case 0x48: - psdp->descr = "Sun FFB2 Horizontal Creator"; break; - case 0x43: - case 0x4b: - psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break; - } - } - break; - } - - xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr); - promPath = sparcPromNode2Pathname (&psdp->node); - if (promPath) { - xf86ErrorF(" at %s", promPath); - free(promPath); - } - } else - xf86Msg(X_PROBED, "SBUS: %s", psdp->descr); - xf86ErrorF("\n"); - } - if (useProm) - sparcPromClose(); -} - -/* - * Parse a BUS ID string, and return the SBUS bus parameters if it was - * in the correct format for a SBUS bus id. - */ - -Bool -xf86ParseSbusBusString(const char *busID, int *fbNum) -{ - /* - * The format is assumed to be one of: - * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN - * "nameN", e.g. "cgsix0", which means Nth instance of card NAME - * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname - * to the device. - */ - - const char *id; - int i, len; - - if (StringToBusType(busID, &id) != BUS_SBUS) - return FALSE; - - if (*id != '/') { - if (!strncmp (id, "fb", 2)) { - if (!isdigit(id[2])) - return FALSE; - *fbNum = atoi(id + 2); - return TRUE; - } else { - sbusDevicePtr *psdpp; - int devId; - - for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) { - len = strlen(sbusDeviceTable[i].promName); - if (!strncmp (sbusDeviceTable[i].promName, id, len) - && isdigit(id[len])) - break; - } - devId = sbusDeviceTable[i].devId; - if (!devId) return FALSE; - i = atoi(id + len); - for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { - if ((*psdpp)->devId != devId) - continue; - if (!i) { - *fbNum = (*psdpp)->fbNum; - return TRUE; - } - i--; - } - } - return FALSE; - } - - if (sparcPromInit() >= 0) { - i = sparcPromPathname2Node(id); - sparcPromClose(); - if (i) { - sbusDevicePtr *psdpp; - for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { - if ((*psdpp)->node.node == i) { - *fbNum = (*psdpp)->fbNum; - return TRUE; - } - } - } - } - return FALSE; -} - -/* - * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match. - */ - -Bool -xf86CompareSbusBusString(const char *busID, int fbNum) -{ - int iFbNum; - - if (xf86ParseSbusBusString(busID, &iFbNum)) { - return fbNum == iFbNum; - } else { - return FALSE; - } -} - -/* - * Check if the slot requested is free. If it is already in use, return FALSE. - */ - -Bool -xf86CheckSbusSlot(int fbNum) -{ - int i; - EntityPtr p; - - for (i = 0; i < xf86NumEntities; i++) { - p = xf86Entities[i]; - /* Check if this SBUS slot is taken */ - if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum) - return FALSE; - } - - return TRUE; -} - -/* - * If the slot requested is already in use, return -1. - * Otherwise, claim the slot for the screen requesting it. - */ - -int -xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp, - GDevPtr dev, Bool active) -{ - EntityPtr p = NULL; - - int num; - - if (xf86CheckSbusSlot(psdp->fbNum)) { - num = xf86AllocateEntity(); - p = xf86Entities[num]; - p->driver = drvp; - p->chipset = -1; - p->bus.type = BUS_SBUS; - xf86AddDevToEntity(num, dev); - p->bus.id.sbus.fbNum = psdp->fbNum; - p->active = active; - p->inUse = FALSE; - sbusSlotClaimed = TRUE; - return num; - } else - return -1; -} - -int -xf86MatchSbusInstances(const char *driverName, int sbusDevId, - GDevPtr *devList, int numDevs, DriverPtr drvp, - int **foundEntities) -{ - int i,j; - sbusDevicePtr psdp, *psdpp; - int numClaimedInstances = 0; - int allocatedInstances = 0; - int numFound = 0; - GDevPtr devBus = NULL; - GDevPtr dev = NULL; - int *retEntities = NULL; - int useProm = 0; - - struct Inst { - sbusDevicePtr sbus; - GDevPtr dev; - Bool claimed; /* BusID matches with a device section */ - } *instances = NULL; - - *foundEntities = NULL; - for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) { - if (psdp->devId != sbusDevId) - continue; - if (psdp->fd == -2) - continue; - ++allocatedInstances; - instances = xnfrealloc(instances, - allocatedInstances * sizeof(struct Inst)); - instances[allocatedInstances - 1].sbus = psdp; - instances[allocatedInstances - 1].dev = NULL; - instances[allocatedInstances - 1].claimed = FALSE; - numFound++; - } - - /* - * This may be debatable, but if no SBUS devices with a matching vendor - * type is found, return zero now. It is probably not desirable to - * allow the config file to override this. - */ - if (allocatedInstances <= 0) { - free(instances); - return 0; - } - - if (sparcPromInit() >= 0) - useProm = 1; - - if (xf86DoConfigure && xf86DoConfigurePass1) { - GDevPtr pGDev; - int actualcards = 0; - for (i = 0; i < allocatedInstances; i++) { - actualcards++; - pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS, - instances[i].sbus, -1); - if (pGDev) { - /* - * XF86Match???Instances() treat chipID and chipRev as - * overrides, so clobber them here. - */ - pGDev->chipID = pGDev->chipRev = -1; - } - } - free(instances); - if (useProm) - sparcPromClose(); - return actualcards; - } - - DebugF("%s instances found: %d\n", driverName, allocatedInstances); - - for (i = 0; i < allocatedInstances; i++) { - char *promPath = NULL; - - psdp = instances[i].sbus; - devBus = NULL; - dev = NULL; - if (useProm && psdp->node.node) - promPath = sparcPromNode2Pathname(&psdp->node); - - for (j = 0; j < numDevs; j++) { - if (devList[j]->busID && *devList[j]->busID) { - if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) { - if (devBus) - xf86MsgVerb(X_WARNING,0, - "%s: More than one matching Device section for " - "instance (BusID: %s) found: %s\n", - driverName,devList[j]->identifier, - devList[j]->busID); - else - devBus = devList[j]; - } - } else { - if (!dev && !devBus) { - if (promPath) - xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n", - promPath); - else - xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n", - psdp->fbNum); - dev = devList[j]; - } else - xf86MsgVerb(X_WARNING, 0, - "%s: More than one matching Device section " - "found: %s\n", driverName, devList[j]->identifier); - } - } - if (devBus) dev = devBus; /* busID preferred */ - if (!dev && psdp->fd != -2) { - if (promPath) { - xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " - "for instance (BusID SBUS:%s) found\n", - driverName, promPath); - } else - xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " - "for instance (BusID SBUS:fb%d) found\n", - driverName, psdp->fbNum); - } else if (dev) { - numClaimedInstances++; - instances[i].claimed = TRUE; - instances[i].dev = dev; - } - free(promPath); - } - - DebugF("%s instances found: %d\n", driverName, numClaimedInstances); - - /* - * Of the claimed instances, check that another driver hasn't already - * claimed its slot. - */ - numFound = 0; - for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) { - if (!instances[i].claimed) - continue; - psdp = instances[i].sbus; - if (!xf86CheckSbusSlot(psdp->fbNum)) - continue; - - DebugF("%s: card at fb%d %08x is claimed by a Device section\n", - driverName, psdp->fbNum, psdp->node.node); - - /* Allocate an entry in the lists to be returned */ - numFound++; - retEntities = xnfrealloc(retEntities, numFound * sizeof(int)); - retEntities[numFound - 1] - = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ? - TRUE : FALSE); - } - free(instances); - if (numFound > 0) { - *foundEntities = retEntities; - } - - if (useProm) - sparcPromClose(); - - return numFound; -} - -/* - * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity. - */ -sbusDevicePtr -xf86GetSbusInfoForEntity(int entityIndex) -{ - sbusDevicePtr *psdpp; - EntityPtr p = xf86Entities[entityIndex]; - - if (entityIndex >= xf86NumEntities - || p->bus.type != BUS_SBUS) return NULL; - - for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) { - if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum) - return *psdpp; - } - return NULL; -} - -int -xf86GetEntityForSbusInfo(sbusDevicePtr psdp) -{ - int i; - - for (i = 0; i < xf86NumEntities; i++) { - EntityPtr p = xf86Entities[i]; - if (p->bus.type != BUS_SBUS) continue; - - if (p->bus.id.sbus.fbNum == psdp->fbNum) - return i; - } - return -1; -} - -void -xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp) -{ - DisplayModePtr mode; - - mode = xnfcalloc(sizeof(DisplayModeRec), 1); - mode->name = "current"; - mode->next = mode; - mode->prev = mode; - mode->type = M_T_BUILTIN; - mode->Clock = 100000000; - mode->HDisplay = psdp->width; - mode->HSyncStart = psdp->width; - mode->HSyncEnd = psdp->width; - mode->HTotal = psdp->width; - mode->VDisplay = psdp->height; - mode->VSyncStart = psdp->height; - mode->VSyncEnd = psdp->height; - mode->VTotal = psdp->height; - mode->SynthClock = mode->Clock; - mode->CrtcHDisplay = mode->HDisplay; - mode->CrtcHSyncStart = mode->HSyncStart; - mode->CrtcHSyncEnd = mode->HSyncEnd; - mode->CrtcHTotal = mode->HTotal; - mode->CrtcVDisplay = mode->VDisplay; - mode->CrtcVSyncStart = mode->VSyncStart; - mode->CrtcVSyncEnd = mode->VSyncEnd; - mode->CrtcVTotal = mode->VTotal; - mode->CrtcHAdjusted = FALSE; - mode->CrtcVAdjusted = FALSE; - pScrn->modes = mode; - pScrn->virtualX = psdp->width; - pScrn->virtualY = psdp->height; -} - -static sbusPaletteKeyIndex; -static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex; -typedef struct _sbusCmap { - sbusDevicePtr psdp; - CloseScreenProcPtr CloseScreen; - Bool origCmapValid; - unsigned char origRed[16]; - unsigned char origGreen[16]; - unsigned char origBlue[16]; -} sbusCmapRec, *sbusCmapPtr; - -#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \ - dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey)) - -static void -xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - LOCO *colors, VisualPtr pVisual) -{ - int i, index; - sbusCmapPtr cmap; - struct fbcmap fbcmap; - unsigned char *data = malloc(numColors*3); - - cmap = SBUSCMAPPTR(pScrn->pScreen); - if (!cmap) return; - fbcmap.count = 0; - fbcmap.index = indices[0]; - fbcmap.red = data; - fbcmap.green = data + numColors; - fbcmap.blue = fbcmap.green + numColors; - for (i = 0; i < numColors; i++) { - index = indices[i]; - if (fbcmap.count && index != fbcmap.index + fbcmap.count) { - ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); - fbcmap.count = 0; - fbcmap.index = index; - } - fbcmap.red[fbcmap.count] = colors[index].red; - fbcmap.green[fbcmap.count] = colors[index].green; - fbcmap.blue[fbcmap.count++] = colors[index].blue; - } - ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); - free(data); -} - -static Bool -xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen) -{ - sbusCmapPtr cmap; - struct fbcmap fbcmap; - - cmap = SBUSCMAPPTR(pScreen); - if (cmap->origCmapValid) { - fbcmap.index = 0; - fbcmap.count = 16; - fbcmap.red = cmap->origRed; - fbcmap.green = cmap->origGreen; - fbcmap.blue = cmap->origBlue; - ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); - } - pScreen->CloseScreen = cmap->CloseScreen; - free(cmap); - return (*pScreen->CloseScreen) (i, pScreen); -} - -Bool -xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp) -{ - sbusCmapPtr cmap; - struct fbcmap fbcmap; - unsigned char data[2]; - - cmap = xnfcalloc(1, sizeof(sbusCmapRec)); - dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap); - cmap->psdp = psdp; - fbcmap.index = 0; - fbcmap.count = 16; - fbcmap.red = cmap->origRed; - fbcmap.green = cmap->origGreen; - fbcmap.blue = cmap->origBlue; - if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0) - cmap->origCmapValid = TRUE; - fbcmap.index = 0; - fbcmap.count = 2; - fbcmap.red = data; - fbcmap.green = data; - fbcmap.blue = data; - if (pScreen->whitePixel == 0) { - data[0] = 255; - data[1] = 0; - } else { - data[0] = 0; - data[1] = 255; - } - ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap); - cmap->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = xf86SbusCmapCloseScreen; - return xf86HandleColormaps(pScreen, 256, 8, - xf86SbusCmapLoadPalette, NULL, 0); -} - -Bool -xf86SbusConfigure(void *busData, sbusDevicePtr sBus) -{ - if (sBus && sBus->fbNum == ((sbusDevicePtr) busData)->fbNum) - return 0; - return 1; -} - -void -xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec *GDev) -{ - char *promPath = NULL; - - sBus = (sbusDevicePtr) busData; - GDev->identifier = sBus->descr; - if (sparcPromInit() >= 0) { - promPath = sparcPromNode2Pathname(&sBus->node); - sparcPromClose(); - } - if (promPath) { - XNFasprintf(&GDev->busID, "SBUS:%s", promPath); - free(promPath); - } else { - XNFsprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum); - } -} +/* + * SBUS bus-specific code. + * + * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) + * + * 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 + * JAKUB JELINEK 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. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86cmap.h" + +#include "xf86Bus.h" + +#include "xf86sbusBus.h" +#include "xf86Sbus.h" + +Bool sbusSlotClaimed = FALSE; + +static int xf86nSbusInfo; + +static void +CheckSbusDevice(const char *device, int fbNum) +{ + int fd, i; + struct fbgattr fbattr; + sbusDevicePtr psdp; + + fd = open(device, O_RDONLY, 0); + if (fd < 0) + return; + memset(&fbattr, 0, sizeof(fbattr)); + if (ioctl(fd, FBIOGATTR, &fbattr) < 0) { + if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) { + close(fd); + return; + } + } + close(fd); + for (i = 0; sbusDeviceTable[i].devId; i++) + if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type) + break; + if (! sbusDeviceTable[i].devId) + return; + xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1)); + xf86SbusInfo[xf86nSbusInfo] = NULL; + xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1); + psdp->devId = sbusDeviceTable[i].devId; + psdp->fbNum = fbNum; + psdp->device = xnfstrdup(device); + psdp->width = fbattr.fbtype.fb_width; + psdp->height = fbattr.fbtype.fb_height; + psdp->fd = -1; +} + +void +xf86SbusProbe(void) +{ + int i, useProm = 0; + char fbDevName[32]; + sbusDevicePtr psdp, *psdpp; + + xf86SbusInfo = malloc(sizeof(psdp)); + *xf86SbusInfo = NULL; + for (i = 0; i < 32; i++) { + sprintf(fbDevName, "/dev/fb%d", i); + CheckSbusDevice(fbDevName, i); + } + if (sparcPromInit() >= 0) { + useProm = 1; + sparcPromAssignNodes(); + } + for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) { + for (i = 0; sbusDeviceTable[i].devId; i++) + if (sbusDeviceTable[i].devId == psdp->devId) + psdp->descr = sbusDeviceTable[i].descr; + /* + * If we can use PROM information and found the PROM node for this + * device, we can tell more about the card. + */ + if (useProm && psdp->node.node) { + char *prop, *promPath; + int len, chiprev, vmsize; + + switch (psdp->devId) { + case SBUS_DEVICE_MGX: + prop = sparcPromGetProperty(&psdp->node, "fb_size", &len); + if (prop && len == 4 && *(int *)prop == 0x400000) + psdp->descr = "Quantum 3D MGXplus with 4M VRAM"; + break; + case SBUS_DEVICE_CG6: + chiprev = 0; + vmsize = 0; + prop = sparcPromGetProperty(&psdp->node, "chiprev", &len); + if (prop && len == 4) + chiprev = *(int *)prop; + prop = sparcPromGetProperty(&psdp->node, "vmsize", &len); + if (prop && len == 4) + vmsize = *(int *)prop; + switch (chiprev) { + case 1: + case 2: + case 3: + case 4: + psdp->descr = "Sun Double width GX"; break; + case 5: + case 6: + case 7: + case 8: + case 9: + psdp->descr = "Sun Single width GX"; break; + case 11: + switch (vmsize) { + case 2: + psdp->descr = "Sun Turbo GX with 1M VSIMM"; break; + case 4: + psdp->descr = "Sun Turbo GX Plus"; break; + default: + psdp->descr = "Sun Turbo GX"; break; + } + } + break; + case SBUS_DEVICE_CG14: + prop = sparcPromGetProperty(&psdp->node, "reg", &len); + vmsize = 0; + if (prop && !(len % 12) && len > 0) + vmsize = *(int *)(prop + len - 4); + switch (vmsize) { + case 0x400000: + psdp->descr = "Sun SX with 4M VSIMM"; break; + case 0x800000: + psdp->descr = "Sun SX with 8M VSIMM"; break; + } + break; + case SBUS_DEVICE_LEO: + prop = sparcPromGetProperty(&psdp->node, "model", &len); + if (prop && len > 0 && !strstr(prop, "501-2503")) + psdp->descr = "Sun Turbo ZX"; + break; + case SBUS_DEVICE_TCX: + if (sparcPromGetBool(&psdp->node, "tcx-8-bit")) + psdp->descr = "Sun TCX (8bit)"; + else + psdp->descr = "Sun TCX (S24)"; + break; + case SBUS_DEVICE_FFB: + prop = sparcPromGetProperty(&psdp->node, "name", &len); + chiprev = 0; + prop = sparcPromGetProperty(&psdp->node, "board_type", &len); + if (prop && len == 4) + chiprev = *(int *)prop; + if (strstr (prop, "afb")) { + if (chiprev == 3) + psdp->descr = "Sun|Elite3D-M6 Horizontal"; + } else { + switch (chiprev) { + case 0x08: + psdp->descr = "Sun FFB 67MHz Creator"; break; + case 0x0b: + psdp->descr = "Sun FFB 67MHz Creator 3D"; break; + case 0x1b: + psdp->descr = "Sun FFB 75MHz Creator 3D"; break; + case 0x20: + case 0x28: + psdp->descr = "Sun FFB2 Vertical Creator"; break; + case 0x23: + case 0x2b: + psdp->descr = "Sun FFB2 Vertical Creator 3D"; break; + case 0x30: + psdp->descr = "Sun FFB2+ Vertical Creator"; break; + case 0x33: + psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break; + case 0x40: + case 0x48: + psdp->descr = "Sun FFB2 Horizontal Creator"; break; + case 0x43: + case 0x4b: + psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break; + } + } + break; + } + + xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr); + promPath = sparcPromNode2Pathname (&psdp->node); + if (promPath) { + xf86ErrorF(" at %s", promPath); + free(promPath); + } + } else + xf86Msg(X_PROBED, "SBUS: %s", psdp->descr); + xf86ErrorF("\n"); + } + if (useProm) + sparcPromClose(); +} + +/* + * Parse a BUS ID string, and return the SBUS bus parameters if it was + * in the correct format for a SBUS bus id. + */ + +Bool +xf86ParseSbusBusString(const char *busID, int *fbNum) +{ + /* + * The format is assumed to be one of: + * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN + * "nameN", e.g. "cgsix0", which means Nth instance of card NAME + * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname + * to the device. + */ + + const char *id; + int i, len; + + if (StringToBusType(busID, &id) != BUS_SBUS) + return FALSE; + + if (*id != '/') { + if (!strncmp (id, "fb", 2)) { + if (!isdigit(id[2])) + return FALSE; + *fbNum = atoi(id + 2); + return TRUE; + } else { + sbusDevicePtr *psdpp; + int devId; + + for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) { + len = strlen(sbusDeviceTable[i].promName); + if (!strncmp (sbusDeviceTable[i].promName, id, len) + && isdigit(id[len])) + break; + } + devId = sbusDeviceTable[i].devId; + if (!devId) return FALSE; + i = atoi(id + len); + for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { + if ((*psdpp)->devId != devId) + continue; + if (!i) { + *fbNum = (*psdpp)->fbNum; + return TRUE; + } + i--; + } + } + return FALSE; + } + + if (sparcPromInit() >= 0) { + i = sparcPromPathname2Node(id); + sparcPromClose(); + if (i) { + sbusDevicePtr *psdpp; + for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { + if ((*psdpp)->node.node == i) { + *fbNum = (*psdpp)->fbNum; + return TRUE; + } + } + } + } + return FALSE; +} + +/* + * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match. + */ + +Bool +xf86CompareSbusBusString(const char *busID, int fbNum) +{ + int iFbNum; + + if (xf86ParseSbusBusString(busID, &iFbNum)) { + return fbNum == iFbNum; + } else { + return FALSE; + } +} + +/* + * Check if the slot requested is free. If it is already in use, return FALSE. + */ + +Bool +xf86CheckSbusSlot(int fbNum) +{ + int i; + EntityPtr p; + + for (i = 0; i < xf86NumEntities; i++) { + p = xf86Entities[i]; + /* Check if this SBUS slot is taken */ + if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum) + return FALSE; + } + + return TRUE; +} + +/* + * If the slot requested is already in use, return -1. + * Otherwise, claim the slot for the screen requesting it. + */ + +int +xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp, + GDevPtr dev, Bool active) +{ + EntityPtr p = NULL; + + int num; + + if (xf86CheckSbusSlot(psdp->fbNum)) { + num = xf86AllocateEntity(); + p = xf86Entities[num]; + p->driver = drvp; + p->chipset = -1; + p->bus.type = BUS_SBUS; + xf86AddDevToEntity(num, dev); + p->bus.id.sbus.fbNum = psdp->fbNum; + p->active = active; + p->inUse = FALSE; + sbusSlotClaimed = TRUE; + return num; + } else + return -1; +} + +int +xf86MatchSbusInstances(const char *driverName, int sbusDevId, + GDevPtr *devList, int numDevs, DriverPtr drvp, + int **foundEntities) +{ + int i,j; + sbusDevicePtr psdp, *psdpp; + int numClaimedInstances = 0; + int allocatedInstances = 0; + int numFound = 0; + GDevPtr devBus = NULL; + GDevPtr dev = NULL; + int *retEntities = NULL; + int useProm = 0; + + struct Inst { + sbusDevicePtr sbus; + GDevPtr dev; + Bool claimed; /* BusID matches with a device section */ + } *instances = NULL; + + *foundEntities = NULL; + for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) { + if (psdp->devId != sbusDevId) + continue; + if (psdp->fd == -2) + continue; + ++allocatedInstances; + instances = xnfrealloc(instances, + allocatedInstances * sizeof(struct Inst)); + instances[allocatedInstances - 1].sbus = psdp; + instances[allocatedInstances - 1].dev = NULL; + instances[allocatedInstances - 1].claimed = FALSE; + numFound++; + } + + /* + * This may be debatable, but if no SBUS devices with a matching vendor + * type is found, return zero now. It is probably not desirable to + * allow the config file to override this. + */ + if (allocatedInstances <= 0) { + free(instances); + return 0; + } + + if (sparcPromInit() >= 0) + useProm = 1; + + if (xf86DoConfigure && xf86DoConfigurePass1) { + GDevPtr pGDev; + int actualcards = 0; + for (i = 0; i < allocatedInstances; i++) { + actualcards++; + pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS, + instances[i].sbus, -1); + if (pGDev) { + /* + * XF86Match???Instances() treat chipID and chipRev as + * overrides, so clobber them here. + */ + pGDev->chipID = pGDev->chipRev = -1; + } + } + free(instances); + if (useProm) + sparcPromClose(); + return actualcards; + } + + DebugF("%s instances found: %d\n", driverName, allocatedInstances); + + for (i = 0; i < allocatedInstances; i++) { + char *promPath = NULL; + + psdp = instances[i].sbus; + devBus = NULL; + dev = NULL; + if (useProm && psdp->node.node) + promPath = sparcPromNode2Pathname(&psdp->node); + + for (j = 0; j < numDevs; j++) { + if (devList[j]->busID && *devList[j]->busID) { + if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) { + if (devBus) + xf86MsgVerb(X_WARNING,0, + "%s: More than one matching Device section for " + "instance (BusID: %s) found: %s\n", + driverName,devList[j]->identifier, + devList[j]->busID); + else + devBus = devList[j]; + } + } else { + if (!dev && !devBus) { + if (promPath) + xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n", + promPath); + else + xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n", + psdp->fbNum); + dev = devList[j]; + } else + xf86MsgVerb(X_WARNING, 0, + "%s: More than one matching Device section " + "found: %s\n", driverName, devList[j]->identifier); + } + } + if (devBus) dev = devBus; /* busID preferred */ + if (!dev && psdp->fd != -2) { + if (promPath) { + xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " + "for instance (BusID SBUS:%s) found\n", + driverName, promPath); + } else + xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " + "for instance (BusID SBUS:fb%d) found\n", + driverName, psdp->fbNum); + } else if (dev) { + numClaimedInstances++; + instances[i].claimed = TRUE; + instances[i].dev = dev; + } + free(promPath); + } + + DebugF("%s instances found: %d\n", driverName, numClaimedInstances); + + /* + * Of the claimed instances, check that another driver hasn't already + * claimed its slot. + */ + numFound = 0; + for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) { + if (!instances[i].claimed) + continue; + psdp = instances[i].sbus; + if (!xf86CheckSbusSlot(psdp->fbNum)) + continue; + + DebugF("%s: card at fb%d %08x is claimed by a Device section\n", + driverName, psdp->fbNum, psdp->node.node); + + /* Allocate an entry in the lists to be returned */ + numFound++; + retEntities = xnfrealloc(retEntities, numFound * sizeof(int)); + retEntities[numFound - 1] + = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ? + TRUE : FALSE); + } + free(instances); + if (numFound > 0) { + *foundEntities = retEntities; + } + + if (useProm) + sparcPromClose(); + + return numFound; +} + +/* + * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity. + */ +sbusDevicePtr +xf86GetSbusInfoForEntity(int entityIndex) +{ + sbusDevicePtr *psdpp; + EntityPtr p = xf86Entities[entityIndex]; + + if (entityIndex >= xf86NumEntities + || p->bus.type != BUS_SBUS) return NULL; + + for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) { + if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum) + return *psdpp; + } + return NULL; +} + +int +xf86GetEntityForSbusInfo(sbusDevicePtr psdp) +{ + int i; + + for (i = 0; i < xf86NumEntities; i++) { + EntityPtr p = xf86Entities[i]; + if (p->bus.type != BUS_SBUS) continue; + + if (p->bus.id.sbus.fbNum == psdp->fbNum) + return i; + } + return -1; +} + +void +xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp) +{ + DisplayModePtr mode; + + mode = xnfcalloc(sizeof(DisplayModeRec), 1); + mode->name = "current"; + mode->next = mode; + mode->prev = mode; + mode->type = M_T_BUILTIN; + mode->Clock = 100000000; + mode->HDisplay = psdp->width; + mode->HSyncStart = psdp->width; + mode->HSyncEnd = psdp->width; + mode->HTotal = psdp->width; + mode->VDisplay = psdp->height; + mode->VSyncStart = psdp->height; + mode->VSyncEnd = psdp->height; + mode->VTotal = psdp->height; + mode->SynthClock = mode->Clock; + mode->CrtcHDisplay = mode->HDisplay; + mode->CrtcHSyncStart = mode->HSyncStart; + mode->CrtcHSyncEnd = mode->HSyncEnd; + mode->CrtcHTotal = mode->HTotal; + mode->CrtcVDisplay = mode->VDisplay; + mode->CrtcVSyncStart = mode->VSyncStart; + mode->CrtcVSyncEnd = mode->VSyncEnd; + mode->CrtcVTotal = mode->VTotal; + mode->CrtcHAdjusted = FALSE; + mode->CrtcVAdjusted = FALSE; + pScrn->modes = mode; + pScrn->virtualX = psdp->width; + pScrn->virtualY = psdp->height; +} + +static sbusPaletteKeyIndex; +static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex; +typedef struct _sbusCmap { + sbusDevicePtr psdp; + CloseScreenProcPtr CloseScreen; + Bool origCmapValid; + unsigned char origRed[16]; + unsigned char origGreen[16]; + unsigned char origBlue[16]; +} sbusCmapRec, *sbusCmapPtr; + +#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey)) + +static void +xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual) +{ + int i, index; + sbusCmapPtr cmap; + struct fbcmap fbcmap; + unsigned char *data = malloc(numColors*3); + + cmap = SBUSCMAPPTR(pScrn->pScreen); + if (!cmap) return; + fbcmap.count = 0; + fbcmap.index = indices[0]; + fbcmap.red = data; + fbcmap.green = data + numColors; + fbcmap.blue = fbcmap.green + numColors; + for (i = 0; i < numColors; i++) { + index = indices[i]; + if (fbcmap.count && index != fbcmap.index + fbcmap.count) { + ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); + fbcmap.count = 0; + fbcmap.index = index; + } + fbcmap.red[fbcmap.count] = colors[index].red; + fbcmap.green[fbcmap.count] = colors[index].green; + fbcmap.blue[fbcmap.count++] = colors[index].blue; + } + ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); + free(data); +} + +static Bool +xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen) +{ + sbusCmapPtr cmap; + struct fbcmap fbcmap; + + cmap = SBUSCMAPPTR(pScreen); + if (cmap->origCmapValid) { + fbcmap.index = 0; + fbcmap.count = 16; + fbcmap.red = cmap->origRed; + fbcmap.green = cmap->origGreen; + fbcmap.blue = cmap->origBlue; + ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); + } + pScreen->CloseScreen = cmap->CloseScreen; + free(cmap); + return (*pScreen->CloseScreen) (i, pScreen); +} + +Bool +xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp) +{ + sbusCmapPtr cmap; + struct fbcmap fbcmap; + unsigned char data[2]; + + cmap = xnfcalloc(1, sizeof(sbusCmapRec)); + dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap); + cmap->psdp = psdp; + fbcmap.index = 0; + fbcmap.count = 16; + fbcmap.red = cmap->origRed; + fbcmap.green = cmap->origGreen; + fbcmap.blue = cmap->origBlue; + if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0) + cmap->origCmapValid = TRUE; + fbcmap.index = 0; + fbcmap.count = 2; + fbcmap.red = data; + fbcmap.green = data; + fbcmap.blue = data; + if (pScreen->whitePixel == 0) { + data[0] = 255; + data[1] = 0; + } else { + data[0] = 0; + data[1] = 255; + } + ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap); + cmap->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = xf86SbusCmapCloseScreen; + return xf86HandleColormaps(pScreen, 256, 8, + xf86SbusCmapLoadPalette, NULL, 0); +} + +Bool +xf86SbusConfigure(void *busData, sbusDevicePtr sBus) +{ + if (sBus && sBus->fbNum == ((sbusDevicePtr) busData)->fbNum) + return 0; + return 1; +} + +void +xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec *GDev) +{ + char *promPath = NULL; + + sBus = (sbusDevicePtr) busData; + GDev->identifier = sBus->descr; + if (sparcPromInit() >= 0) { + promPath = sparcPromNode2Pathname(&sBus->node); + sparcPromClose(); + } + if (promPath) { + XNFasprintf(&GDev->busID, "SBUS:%s", promPath); + free(promPath); + } else { + XNFasprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum); + } +} diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index d721b131f..86f038aa1 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -1,3281 +1,3242 @@ -/* - * Copyright © 2006 Keith Packard - * Copyright © 2008 Red Hat, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#else -#ifdef HAVE_CONFIG_H -#include -#endif -#endif - -#include -#include -#include - -#include "xf86.h" -#include "xf86DDC.h" -#include "xf86Crtc.h" -#include "xf86Modes.h" -#include "xf86Priv.h" -#include "xf86RandR12.h" -#include "X11/extensions/render.h" -#include "X11/extensions/dpmsconst.h" -#include "X11/Xatom.h" -#include "picturestr.h" - -#include "xf86xv.h" - -#define NO_OUTPUT_DEFAULT_WIDTH 1024 -#define NO_OUTPUT_DEFAULT_HEIGHT 768 -/* - * Initialize xf86CrtcConfig structure - */ - -int xf86CrtcConfigPrivateIndex = -1; - -void -xf86CrtcConfigInit (ScrnInfoPtr scrn, - const xf86CrtcConfigFuncsRec *funcs) -{ - xf86CrtcConfigPtr config; - - if (xf86CrtcConfigPrivateIndex == -1) - xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); - config = xnfcalloc (1, sizeof (xf86CrtcConfigRec)); - - config->funcs = funcs; - - scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config; -} - -void -xf86CrtcSetSizeRange (ScrnInfoPtr scrn, - int minWidth, int minHeight, - int maxWidth, int maxHeight) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - - config->minWidth = minWidth; - config->minHeight = minHeight; - config->maxWidth = maxWidth; - config->maxHeight = maxHeight; -} - -void -xf86CrtcSetScanoutFormats(ScrnInfoPtr scrn, - int num_formats, - xf86CrtcScanoutFormat *formats) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - - config->num_scanout_formats = num_formats; - config->scanout_formats = formats; -} - -/* - * Crtc functions - */ -xf86CrtcPtr -xf86CrtcCreate (ScrnInfoPtr scrn, - const xf86CrtcFuncsRec *funcs) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CrtcPtr crtc, *crtcs; - - crtc = calloc(sizeof (xf86CrtcRec), 1); - if (!crtc) - return NULL; - crtc->version = XF86_CRTC_VERSION; - crtc->scrn = scrn; - crtc->funcs = funcs; -#ifdef RANDR_12_INTERFACE - crtc->randr_crtc = NULL; -#endif - crtc->rotation = RR_Rotate_0; - crtc->desiredRotation = RR_Rotate_0; - pixman_transform_init_identity (&crtc->crtc_to_framebuffer); - pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer); - pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc); - pixman_f_transform_init_identity (&crtc->f_screen_to_crtc); - pixman_f_transform_init_identity (&crtc->user_sprite_position_transform); - pixman_f_transform_init_identity (&crtc->f_crtc_to_cursor); - pixman_f_transform_init_identity (&crtc->user_sprite_image_transform); - crtc->filter = NULL; - crtc->params = NULL; - crtc->nparams = 0; - crtc->filter_width = 0; - crtc->filter_height = 0; - crtc->transform_in_use = FALSE; - crtc->sprite_transform_in_use = FALSE; - crtc->transformPresent = FALSE; - crtc->desiredTransformPresent = FALSE; - memset (&crtc->bounds, '\0', sizeof (crtc->bounds)); - - /* Preallocate gamma at a sensible size. */ - crtc->gamma_size = 256; - crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof (CARD16)); - if (!crtc->gamma_red) { - free(crtc); - return NULL; - } - crtc->gamma_green = crtc->gamma_red + crtc->gamma_size; - crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size; - - if (xf86_config->crtc) - crtcs = realloc(xf86_config->crtc, - (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr)); - else - crtcs = malloc((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr)); - if (!crtcs) - { - free(crtc); - return NULL; - } - xf86_config->crtc = crtcs; - xf86_config->crtc[xf86_config->num_crtc++] = crtc; - return crtc; -} - -void -xf86CrtcDestroy (xf86CrtcPtr crtc) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); - int c; - - (*crtc->funcs->destroy) (crtc); - for (c = 0; c < xf86_config->num_crtc; c++) - if (xf86_config->crtc[c] == crtc) - { - memmove (&xf86_config->crtc[c], - &xf86_config->crtc[c+1], - ((xf86_config->num_crtc - (c + 1)) * sizeof(void*))); - xf86_config->num_crtc--; - break; - } - free(crtc->params); - free(crtc->gamma_red); - free(crtc); -} - - -/** - * Return whether any outputs are connected to the specified pipe - */ - -Bool -xf86CrtcInUse (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int o; - - for (o = 0; o < xf86_config->num_output; o++) - if (xf86_config->output[o]->crtc == crtc) - return TRUE; - return FALSE; -} - -void -xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen) -{ - int subpixel_order = SubPixelUnknown; - Bool has_none = FALSE; - ScrnInfoPtr scrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c, o; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - for (o = 0; o < xf86_config->num_output; o++) - { - xf86OutputPtr output = xf86_config->output[o]; - - if (output->crtc == crtc) - { - switch (output->subpixel_order) { - case SubPixelNone: - has_none = TRUE; - break; - case SubPixelUnknown: - break; - default: - subpixel_order = output->subpixel_order; - break; - } - } - if (subpixel_order != SubPixelUnknown) - break; - } - if (subpixel_order != SubPixelUnknown) - { - static const int circle[4] = { - SubPixelHorizontalRGB, - SubPixelVerticalRGB, - SubPixelHorizontalBGR, - SubPixelVerticalBGR, - }; - int rotate; - int c; - for (rotate = 0; rotate < 4; rotate++) - if (crtc->rotation & (1 << rotate)) - break; - for (c = 0; c < 4; c++) - if (circle[c] == subpixel_order) - break; - c = (c + rotate) & 0x3; - if ((crtc->rotation & RR_Reflect_X) && !(c & 1)) - c ^= 2; - if ((crtc->rotation & RR_Reflect_Y) && (c & 1)) - c ^= 2; - subpixel_order = circle[c]; - break; - } - } - if (subpixel_order == SubPixelUnknown && has_none) - subpixel_order = SubPixelNone; - PictureSetSubpixelOrder (pScreen, subpixel_order); -} - -/** - * Sets the given video mode on the given crtc - */ -Bool -xf86CrtcSet(xf86CrtcPtr crtc, xf86CrtcSetRec *set) -{ - ScrnInfoPtr scrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int i; - Bool ret = FALSE; - Bool didLock = FALSE; - DisplayModePtr adjusted_mode = NULL; - DisplayModeRec saved_mode; - int saved_x, saved_y; - Rotation saved_rotation; - RRTransformRec saved_transform; - Bool saved_transform_present; - PixmapPtr saved_scanout_pixmap; - - crtc->enabled = xf86CrtcInUse (crtc); - - /* We only hit this if someone explicitly sends a "disabled" modeset. */ - if (!crtc->enabled) - { - /* Check everything for stuff that should be off. */ - xf86DisableUnusedFunctions(scrn); - return TRUE; - } - - /* See if nothing has changed */ - if (!set->flags) - return TRUE; - - saved_mode = crtc->mode; - saved_x = crtc->x; - saved_y = crtc->y; - saved_rotation = crtc->rotation; - saved_scanout_pixmap = crtc->scanoutPixmap; - if (crtc->transformPresent) { - RRTransformInit (&saved_transform); - RRTransformCopy (&saved_transform, &crtc->transform); - } - saved_transform_present = crtc->transformPresent; - - /* Update crtc values up front so the driver can rely on them for mode - * setting. - */ - if (set->flags & XF86CrtcSetMode) - crtc->mode = *set->mode; - if (set->flags & XF86CrtcSetOrigin) { - crtc->x = set->x; - crtc->y = set->y; - } - if (set->flags & XF86CrtcSetRotation) - crtc->rotation = set->rotation; - if (set->flags & XF86CrtcSetScanoutPixmap) - crtc->scanoutPixmap = set->scanout_pixmap; - - if (set->flags & XF86CrtcSetTransform) { - if (set->transform) { - RRTransformCopy (&crtc->transform, set->transform); - crtc->transformPresent = TRUE; - } else - crtc->transformPresent = FALSE; - } - - if (crtc->funcs->set) { - ret = crtc->funcs->set(crtc, set->flags); - goto done; - } - - if (set->flags == XF86CrtcSetOrigin && crtc->funcs->set_origin) { - ret = xf86CrtcRotate(crtc); - if (ret) - crtc->funcs->set_origin(crtc, crtc->x, crtc->y); - goto done; - } - - if (crtc->funcs->set_mode_major) { - ret = crtc->funcs->set_mode_major(crtc, &crtc->mode, - crtc->rotation, - crtc->x, crtc->y); - goto done; - } - - adjusted_mode = xf86DuplicateMode(&crtc->mode); - - didLock = crtc->funcs->lock (crtc); - /* Pass our mode to the outputs and the CRTC to give them a chance to - * adjust it according to limitations or output properties, and also - * a chance to reject the mode entirely. - */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - - if (output->crtc != crtc) - continue; - - if (!output->funcs->mode_fixup(output, &crtc->mode, adjusted_mode)) { - goto done; - } - } - - if (!crtc->funcs->mode_fixup(crtc, &crtc->mode, adjusted_mode)) { - goto done; - } - - if (!xf86CrtcRotate (crtc)) - goto done; - - /* Prepare the outputs and CRTCs before setting the mode. */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - - if (output->crtc != crtc) - continue; - - /* Disable the output as the first thing we do. */ - output->funcs->prepare(output); - } - - crtc->funcs->prepare(crtc); - - /* Set up the DPLL and any output state that needs to adjust or depend - * on the DPLL. - */ - crtc->funcs->mode_set(crtc, &crtc->mode, adjusted_mode, crtc->x, crtc->y); - for (i = 0; i < xf86_config->num_output; i++) - { - xf86OutputPtr output = xf86_config->output[i]; - if (output->crtc == crtc) - output->funcs->mode_set(output, &crtc->mode, adjusted_mode); - } - - /* Only upload when needed, to avoid unneeded delays. */ - if (!crtc->active && crtc->funcs->gamma_set) - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); - - /* Now, enable the clocks, plane, pipe, and outputs that we set up. */ - crtc->funcs->commit(crtc); - for (i = 0; i < xf86_config->num_output; i++) - { - xf86OutputPtr output = xf86_config->output[i]; - if (output->crtc == crtc) - output->funcs->commit(output); - } - - ret = TRUE; - -done: - if (ret) { - crtc->active = TRUE; - if (scrn->pScreen) - xf86CrtcSetScreenSubpixelOrder (scrn->pScreen); - if (scrn->ModeSet) - scrn->ModeSet(scrn); - } else { - crtc->x = saved_x; - crtc->y = saved_y; - crtc->rotation = saved_rotation; - crtc->mode = saved_mode; - if (saved_transform_present) - RRTransformCopy (&crtc->transform, &saved_transform); - crtc->transformPresent = saved_transform_present; - crtc->scanoutPixmap = saved_scanout_pixmap; - } - - if (adjusted_mode) { - free(adjusted_mode->name); - free(adjusted_mode); - } - - if (didLock) - crtc->funcs->unlock (crtc); - - return ret; -} - -/** - * Pans the screen, does not change the mode - */ -void -xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y) -{ - xf86CrtcSetRec set; - - if (x != crtc->x || y != crtc->y) { - set.x = x; - set.y = y; - set.flags = XF86CrtcSetOrigin; - (void) xf86CrtcSet(crtc, &set); - } -} - -/* - * Output functions - */ - -extern XF86ConfigPtr xf86configptr; - -typedef enum { - OPTION_PREFERRED_MODE, - OPTION_POSITION, - OPTION_BELOW, - OPTION_RIGHT_OF, - OPTION_ABOVE, - OPTION_LEFT_OF, - OPTION_ENABLE, - OPTION_DISABLE, - OPTION_MIN_CLOCK, - OPTION_MAX_CLOCK, - OPTION_IGNORE, - OPTION_ROTATE, - OPTION_PANNING, - OPTION_PRIMARY, - OPTION_DEFAULT_MODES, -} OutputOpts; - -static OptionInfoRec xf86OutputOptions[] = { - {OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE }, - {OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE }, - {OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE }, - {OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE }, - {OPTION_ABOVE, "Above", OPTV_STRING, {0}, FALSE }, - {OPTION_LEFT_OF, "LeftOf", OPTV_STRING, {0}, FALSE }, - {OPTION_ENABLE, "Enable", OPTV_BOOLEAN, {0}, FALSE }, - {OPTION_DISABLE, "Disable", OPTV_BOOLEAN, {0}, FALSE }, - {OPTION_MIN_CLOCK, "MinClock", OPTV_FREQ, {0}, FALSE }, - {OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE }, - {OPTION_IGNORE, "Ignore", OPTV_BOOLEAN, {0}, FALSE }, - {OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE }, - {OPTION_PANNING, "Panning", OPTV_STRING, {0}, FALSE }, - {OPTION_PRIMARY, "Primary", OPTV_BOOLEAN, {0}, FALSE }, - {OPTION_DEFAULT_MODES, "DefaultModes", OPTV_BOOLEAN, {0}, FALSE }, - {-1, NULL, OPTV_NONE, {0}, FALSE }, -}; - -enum { - OPTION_MODEDEBUG, -}; - -static OptionInfoRec xf86DeviceOptions[] = { - {OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE }, - {-1, NULL, OPTV_NONE, {0}, FALSE }, -}; - -static void -xf86OutputSetMonitor (xf86OutputPtr output) -{ - char *option_name; - char *monitor; - - if (!output->name) - return; - - free(output->options); - - output->options = xnfalloc (sizeof (xf86OutputOptions)); - memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions)); - - XNFasprintf(&option_name, "monitor-%s", output->name); - monitor = xf86findOptionValue (output->scrn->options, option_name); - if (!monitor) - monitor = output->name; - else - xf86MarkOptionUsedByName (output->scrn->options, option_name); - free(option_name); - output->conf_monitor = xf86findMonitor (monitor, - xf86configptr->conf_monitor_lst); - /* - * Find the monitor section of the screen and use that - */ - if (!output->conf_monitor && output->use_screen_monitor) - output->conf_monitor = xf86findMonitor (output->scrn->monitor->id, - xf86configptr->conf_monitor_lst); - if (output->conf_monitor) - { - xf86DrvMsg (output->scrn->scrnIndex, X_INFO, - "Output %s using monitor section %s\n", - output->name, output->conf_monitor->mon_identifier); - xf86ProcessOptions (output->scrn->scrnIndex, - output->conf_monitor->mon_option_lst, - output->options); - } - else - xf86DrvMsg (output->scrn->scrnIndex, X_INFO, - "Output %s has no monitor section\n", - output->name); -} - -static Bool -xf86OutputEnabled (xf86OutputPtr output, Bool strict) -{ - Bool enable, disable; - - /* check to see if this output was enabled in the config file */ - if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable) - { - xf86DrvMsg (output->scrn->scrnIndex, X_INFO, - "Output %s enabled by config file\n", output->name); - return TRUE; - } - /* or if this output was disabled in the config file */ - if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable) - { - xf86DrvMsg (output->scrn->scrnIndex, X_INFO, - "Output %s disabled by config file\n", output->name); - return FALSE; - } - - /* If not, try to only light up the ones we know are connected */ - if (strict) { - enable = output->status == XF86OutputStatusConnected; - } - /* But if that fails, try to light up even outputs we're unsure of */ - else { - enable = output->status != XF86OutputStatusDisconnected; - } - - xf86DrvMsg (output->scrn->scrnIndex, X_INFO, - "Output %s %sconnected\n", output->name, enable ? "" : "dis"); - return enable; -} - -static Bool -xf86OutputIgnored (xf86OutputPtr output) -{ - return xf86ReturnOptValBool (output->options, OPTION_IGNORE, FALSE); -} - -static char *direction[4] = { - "normal", - "left", - "inverted", - "right" -}; - -static Rotation -xf86OutputInitialRotation (xf86OutputPtr output) -{ - char *rotate_name = xf86GetOptValString (output->options, - OPTION_ROTATE); - int i; - - if (!rotate_name) { - if (output->initial_rotation) - return output->initial_rotation; - return RR_Rotate_0; - } - - for (i = 0; i < 4; i++) - if (xf86nameCompare (direction[i], rotate_name) == 0) - return 1 << i; - return RR_Rotate_0; -} - -xf86OutputPtr -xf86OutputCreate (ScrnInfoPtr scrn, - const xf86OutputFuncsRec *funcs, - const char *name) -{ - xf86OutputPtr output, *outputs; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int len; - Bool primary; - - if (name) - len = strlen (name) + 1; - else - len = 0; - - output = calloc(sizeof (xf86OutputRec) + len, 1); - if (!output) - return NULL; - output->scrn = scrn; - output->funcs = funcs; - if (name) - { - output->name = (char *) (output + 1); - strcpy (output->name, name); - } - output->subpixel_order = SubPixelUnknown; - /* - * Use the old per-screen monitor section for the first output - */ - output->use_screen_monitor = (xf86_config->num_output == 0); -#ifdef RANDR_12_INTERFACE - output->randr_output = NULL; -#endif - if (name) - { - xf86OutputSetMonitor (output); - if (xf86OutputIgnored (output)) - { - free(output); - return FALSE; - } - } - - - if (xf86_config->output) - outputs = realloc(xf86_config->output, - (xf86_config->num_output + 1) * sizeof (xf86OutputPtr)); - else - outputs = malloc((xf86_config->num_output + 1) * sizeof (xf86OutputPtr)); - if (!outputs) - { - free(output); - return NULL; - } - - xf86_config->output = outputs; - - if (xf86GetOptValBool (output->options, OPTION_PRIMARY, &primary) && primary) - { - memmove(xf86_config->output + 1, xf86_config->output, - xf86_config->num_output * sizeof (xf86OutputPtr)); - xf86_config->output[0] = output; - } - else - { - xf86_config->output[xf86_config->num_output] = output; - } - - xf86_config->num_output++; - - return output; -} - -Bool -xf86OutputRename (xf86OutputPtr output, const char *name) -{ - char *newname = strdup(name); - - if (!newname) - return FALSE; /* so sorry... */ - - if (output->name && output->name != (char *) (output + 1)) - free(output->name); - output->name = newname; - xf86OutputSetMonitor (output); - if (xf86OutputIgnored (output)) - return FALSE; - return TRUE; -} - -void -xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor) -{ - if (use_screen_monitor != output->use_screen_monitor) - { - output->use_screen_monitor = use_screen_monitor; - xf86OutputSetMonitor (output); - } -} - -void -xf86OutputDestroy (xf86OutputPtr output) -{ - ScrnInfoPtr scrn = output->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int o; - - (*output->funcs->destroy) (output); - while (output->probed_modes) - xf86DeleteMode (&output->probed_modes, output->probed_modes); - for (o = 0; o < xf86_config->num_output; o++) - if (xf86_config->output[o] == output) - { - memmove (&xf86_config->output[o], - &xf86_config->output[o+1], - ((xf86_config->num_output - (o + 1)) * sizeof(void*))); - xf86_config->num_output--; - break; - } - if (output->name && output->name != (char *) (output + 1)) - free(output->name); - free(output); -} - -/* - * Called during CreateScreenResources to hook up RandR - */ -static Bool -xf86CrtcCreateScreenResources (ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - - screen->CreateScreenResources = config->CreateScreenResources; - - if (!(*screen->CreateScreenResources)(screen)) - return FALSE; - - if (!xf86RandR12CreateScreenResources (screen)) - return FALSE; - - return TRUE; -} - -/* - * Clean up config on server reset - */ -static Bool -xf86CrtcCloseScreen (int index, ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int o, c; - - screen->CloseScreen = config->CloseScreen; - - xf86RotateCloseScreen (screen); - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - output->randr_output = NULL; - } - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - - crtc->randr_crtc = NULL; - } - xf86RandR12CloseScreen (screen); - - return screen->CloseScreen (index, screen); -} - -/* - * Called at ScreenInit time to set up - */ -#ifdef RANDR_13_INTERFACE -int -#else -Bool -#endif -xf86CrtcScreenInit (ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - /* Rotation */ - xf86DrvMsg(scrn->scrnIndex, X_INFO, "RandR 1.2 enabled, ignore the following RandR disabled message.\n"); - xf86DisableRandR(); /* Disable old RandR extension support */ - xf86RandR12Init (screen); - - /* support all rotations if every crtc has the shadow alloc funcs */ - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - if (!crtc->funcs->shadow_allocate || !crtc->funcs->shadow_create) - break; - } - if (c == config->num_crtc) - { - xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 | - RR_Rotate_180 | RR_Rotate_270 | - RR_Reflect_X | RR_Reflect_Y); - xf86RandR12SetTransformSupport (screen, TRUE); - } - else - { - xf86RandR12SetRotations (screen, RR_Rotate_0); - xf86RandR12SetTransformSupport (screen, FALSE); - } - - /* Wrap CreateScreenResources so we can initialize the RandR code */ - config->CreateScreenResources = screen->CreateScreenResources; - screen->CreateScreenResources = xf86CrtcCreateScreenResources; - - config->CloseScreen = screen->CloseScreen; - screen->CloseScreen = xf86CrtcCloseScreen; - -#ifdef XFreeXDGA - _xf86_di_dga_init_internal(screen); -#endif -#ifdef RANDR_13_INTERFACE - return RANDR_INTERFACE_VERSION; -#else - return TRUE; -#endif -} - -static DisplayModePtr -xf86DefaultMode (xf86OutputPtr output, int width, int height) -{ - DisplayModePtr target_mode = NULL; - DisplayModePtr mode; - int target_diff = 0; - int target_preferred = 0; - int mm_height; - - mm_height = output->mm_height; - if (!mm_height) - mm_height = (768 * 25.4) / DEFAULT_DPI; - /* - * Pick a mode closest to DEFAULT_DPI - */ - for (mode = output->probed_modes; mode; mode = mode->next) - { - int dpi; - int preferred = (((mode->type & M_T_PREFERRED) != 0) + - ((mode->type & M_T_USERPREF) != 0)); - int diff; - - if (xf86ModeWidth (mode, output->initial_rotation) > width || - xf86ModeHeight (mode, output->initial_rotation) > height) - continue; - - /* yes, use VDisplay here, not xf86ModeHeight */ - dpi = (mode->VDisplay * 254) / (mm_height * 10); - diff = dpi - DEFAULT_DPI; - diff = diff < 0 ? -diff : diff; - if (target_mode == NULL || (preferred > target_preferred) || - (preferred == target_preferred && diff < target_diff)) - { - target_mode = mode; - target_diff = diff; - target_preferred = preferred; - } - } - return target_mode; -} - -static DisplayModePtr -xf86ClosestMode (xf86OutputPtr output, - DisplayModePtr match, Rotation match_rotation, - int width, int height) -{ - DisplayModePtr target_mode = NULL; - DisplayModePtr mode; - int target_diff = 0; - - /* - * Pick a mode closest to the specified mode - */ - for (mode = output->probed_modes; mode; mode = mode->next) - { - int dx, dy; - int diff; - - if (xf86ModeWidth (mode, output->initial_rotation) > width || - xf86ModeHeight (mode, output->initial_rotation) > height) - continue; - - /* exact matches are preferred */ - if (output->initial_rotation == match_rotation && - xf86ModesEqual (mode, match)) - return mode; - - dx = xf86ModeWidth (match, match_rotation) - xf86ModeWidth (mode, output->initial_rotation); - dy = xf86ModeHeight (match, match_rotation) - xf86ModeHeight (mode, output->initial_rotation); - diff = dx * dx + dy * dy; - if (target_mode == NULL || diff < target_diff) - { - target_mode = mode; - target_diff = diff; - } - } - return target_mode; -} - -static DisplayModePtr -xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height) -{ - DisplayModePtr mode; - - for (mode = output->probed_modes; mode; mode = mode->next) - { - if (xf86ModeWidth (mode, output->initial_rotation) > width || - xf86ModeHeight (mode, output->initial_rotation) > height) - continue; - - if (mode->type & M_T_PREFERRED) - return mode; - } - return NULL; -} - -static DisplayModePtr -xf86OutputHasUserPreferredMode (xf86OutputPtr output) -{ - DisplayModePtr mode, first = output->probed_modes; - - for (mode = first; mode && mode->next != first; mode = mode->next) - if (mode->type & M_T_USERPREF) - return mode; - - return NULL; -} - -static int -xf86PickCrtcs (ScrnInfoPtr scrn, - xf86CrtcPtr *best_crtcs, - DisplayModePtr *modes, - int n, - int width, - int height) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int c, o; - xf86OutputPtr output; - xf86CrtcPtr crtc; - xf86CrtcPtr *crtcs; - xf86CrtcPtr best_crtc; - int best_score; - int score; - int my_score; - - if (n == config->num_output) - return 0; - output = config->output[n]; - - /* - * Compute score with this output disabled - */ - best_crtcs[n] = NULL; - best_crtc = NULL; - best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height); - if (modes[n] == NULL) - return best_score; - - crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr)); - if (!crtcs) - return best_score; - - my_score = 1; - /* Score outputs that are known to be connected higher */ - if (output->status == XF86OutputStatusConnected) - my_score++; - /* Score outputs with preferred modes higher */ - if (xf86OutputHasPreferredMode (output, width, height)) - my_score++; - /* - * Select a crtc for this output and - * then attempt to configure the remaining - * outputs - */ - for (c = 0; c < config->num_crtc; c++) - { - if ((output->possible_crtcs & (1 << c)) == 0) - continue; - - crtc = config->crtc[c]; - /* - * Check to see if some other output is - * using this crtc - */ - for (o = 0; o < n; o++) - if (best_crtcs[o] == crtc) - break; - if (o < n) - { - /* - * If the two outputs desire the same mode, - * see if they can be cloned - */ - if (xf86ModesEqual (modes[o], modes[n]) && - config->output[o]->initial_rotation == config->output[n]->initial_rotation && - config->output[o]->initial_x == config->output[n]->initial_x && - config->output[o]->initial_y == config->output[n]->initial_y) - { - if ((output->possible_clones & (1 << o)) == 0) - continue; /* nope, try next CRTC */ - } - else - continue; /* different modes, can't clone */ - } - crtcs[n] = crtc; - memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr)); - score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height); - if (score > best_score) - { - best_crtc = crtc; - best_score = score; - memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr)); - } - } - free(crtcs); - return best_score; -} - - -/* - * Compute the virtual size necessary to place all of the available - * crtcs in the specified configuration. - * - * canGrow indicates that the driver can make the screen larger than its initial - * configuration. If FALSE, this function will enlarge the screen to include - * the largest available mode. - */ - -static void -xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp, - Bool canGrow) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int width = 0, height = 0; - int o; - int c; - int s; - - for (c = 0; c < config->num_crtc; c++) - { - int crtc_width = 0, crtc_height = 0; - xf86CrtcPtr crtc = config->crtc[c]; - - if (crtc->enabled) - { - crtc_width = crtc->desiredX + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation); - crtc_height = crtc->desiredY + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation); - } - if (!canGrow) { - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - for (s = 0; s < config->num_crtc; s++) - if (output->possible_crtcs & (1 << s)) - { - DisplayModePtr mode; - for (mode = output->probed_modes; mode; mode = mode->next) - { - if (mode->HDisplay > crtc_width) - crtc_width = mode->HDisplay; - if (mode->VDisplay > crtc_width) - crtc_width = mode->VDisplay; - if (mode->VDisplay > crtc_height) - crtc_height = mode->VDisplay; - if (mode->HDisplay > crtc_height) - crtc_height = mode->HDisplay; - } - } - } - } - if (crtc_width > width) - width = crtc_width; - if (crtc_height > height) - height = crtc_height; - } - if (config->maxWidth && width > config->maxWidth) width = config->maxWidth; - if (config->maxHeight && height > config->maxHeight) height = config->maxHeight; - if (config->minWidth && width < config->minWidth) width = config->minWidth; - if (config->minHeight && height < config->minHeight) height = config->minHeight; - *widthp = width; - *heightp = height; -} - -#define POSITION_UNSET -100000 - -/* - * check if the user configured any outputs at all - * with either a position or a relative setting or a mode. - */ -static Bool -xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int o; - Bool user_conf = FALSE; - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - char *position; - char *relative_name; - OutputOpts relation; - int r; - static const OutputOpts relations[] = { - OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF - }; - - position = xf86GetOptValString (output->options, - OPTION_POSITION); - if (position) - user_conf = TRUE; - - relation = 0; - relative_name = NULL; - for (r = 0; r < 4; r++) - { - relation = relations[r]; - relative_name = xf86GetOptValString (output->options, - relation); - if (relative_name) - break; - } - if (relative_name) - user_conf = TRUE; - - modes[o] = xf86OutputHasUserPreferredMode(output); - if (modes[o]) - user_conf = TRUE; - } - - return user_conf; -} - -static Bool -xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int o; - int min_x, min_y; - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - output->initial_x = output->initial_y = POSITION_UNSET; - } - - /* - * Loop until all outputs are set - */ - for (;;) - { - Bool any_set = FALSE; - Bool keep_going = FALSE; - - for (o = 0; o < config->num_output; o++) - { - static const OutputOpts relations[] = { - OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF - }; - xf86OutputPtr output = config->output[o]; - xf86OutputPtr relative; - char *relative_name; - char *position; - OutputOpts relation; - int r; - - if (output->initial_x != POSITION_UNSET) - continue; - position = xf86GetOptValString (output->options, - OPTION_POSITION); - /* - * Absolute position wins - */ - if (position) - { - int x, y; - if (sscanf (position, "%d %d", &x, &y) == 2) - { - output->initial_x = x; - output->initial_y = y; - } - else - { - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Output %s position not of form \"x y\"\n", - output->name); - output->initial_x = output->initial_y = 0; - } - any_set = TRUE; - continue; - } - /* - * Next comes relative positions - */ - relation = 0; - relative_name = NULL; - for (r = 0; r < 4; r++) - { - relation = relations[r]; - relative_name = xf86GetOptValString (output->options, - relation); - if (relative_name) - break; - } - if (relative_name) - { - int or; - relative = NULL; - for (or = 0; or < config->num_output; or++) - { - xf86OutputPtr out_rel = config->output[or]; - XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor; - - if (rel_mon) - { - if (xf86nameCompare (rel_mon->mon_identifier, - relative_name) == 0) - { - relative = config->output[or]; - break; - } - } - if (strcmp (out_rel->name, relative_name) == 0) - { - relative = config->output[or]; - break; - } - } - if (!relative) - { - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Cannot position output %s relative to unknown output %s\n", - output->name, relative_name); - output->initial_x = 0; - output->initial_y = 0; - any_set = TRUE; - continue; - } - if (!modes[or]) - { - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Cannot position output %s relative to output %s without modes\n", - output->name, relative_name); - output->initial_x = 0; - output->initial_y = 0; - any_set = TRUE; - continue; - } - if (relative->initial_x == POSITION_UNSET) - { - keep_going = TRUE; - continue; - } - output->initial_x = relative->initial_x; - output->initial_y = relative->initial_y; - switch (relation) { - case OPTION_BELOW: - output->initial_y += xf86ModeHeight (modes[or], relative->initial_rotation); - break; - case OPTION_RIGHT_OF: - output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation); - break; - case OPTION_ABOVE: - if (modes[o]) - output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation); - break; - case OPTION_LEFT_OF: - if (modes[o]) - output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation); - break; - default: - break; - } - any_set = TRUE; - continue; - } - - /* Nothing set, just stick them at 0,0 */ - output->initial_x = 0; - output->initial_y = 0; - any_set = TRUE; - } - if (!keep_going) - break; - if (!any_set) - { - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - if (output->initial_x == POSITION_UNSET) - { - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Output position loop. Moving %s to 0,0\n", - output->name); - output->initial_x = output->initial_y = 0; - break; - } - } - } - } - - /* - * normalize positions - */ - min_x = 1000000; - min_y = 1000000; - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - if (output->initial_x < min_x) - min_x = output->initial_x; - if (output->initial_y < min_y) - min_y = output->initial_y; - } - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - output->initial_x -= min_x; - output->initial_y -= min_y; - } - return TRUE; -} - -static void -xf86InitialPanning (ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int o; - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - char *panning = xf86GetOptValString (output->options, OPTION_PANNING); - int width, height, left, top; - int track_width, track_height, track_left, track_top; - int brdr[4]; - - memset (&output->initialTotalArea, 0, sizeof(BoxRec)); - memset (&output->initialTrackingArea, 0, sizeof(BoxRec)); - memset (output->initialBorder, 0, 4*sizeof(INT16)); - - if (! panning) - continue; - - switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d", - &width, &height, &left, &top, - &track_width, &track_height, &track_left, &track_top, - &brdr[0], &brdr[1], &brdr[2], &brdr[3])) { - case 12: - output->initialBorder[0] = brdr[0]; - output->initialBorder[1] = brdr[1]; - output->initialBorder[2] = brdr[2]; - output->initialBorder[3] = brdr[3]; - /* fall through */ - case 8: - output->initialTrackingArea.x1 = track_left; - output->initialTrackingArea.y1 = track_top; - output->initialTrackingArea.x2 = track_left + track_width; - output->initialTrackingArea.y2 = track_top + track_height; - /* fall through */ - case 4: - output->initialTotalArea.x1 = left; - output->initialTotalArea.y1 = top; - /* fall through */ - case 2: - output->initialTotalArea.x2 = output->initialTotalArea.x1 + width; - output->initialTotalArea.y2 = output->initialTotalArea.y1 + height; - break; - default: - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Broken panning specification '%s' for output %s in config file\n", - panning, output->name); - } - } -} - -/** Return - 0 + if a should be earlier, same or later than b in list - */ -static int -xf86ModeCompare (DisplayModePtr a, DisplayModePtr b) -{ - int diff; - - diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0); - if (diff) - return diff; - diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay; - if (diff) - return diff; - diff = b->Clock - a->Clock; - return diff; -} - -/** - * Insertion sort input in-place and return the resulting head - */ -static DisplayModePtr -xf86SortModes (DisplayModePtr input) -{ - DisplayModePtr output = NULL, i, o, n, *op, prev; - - /* sort by preferred status and pixel area */ - while (input) - { - i = input; - input = input->next; - for (op = &output; (o = *op); op = &o->next) - if (xf86ModeCompare (o, i) > 0) - break; - i->next = *op; - *op = i; - } - /* prune identical modes */ - for (o = output; o && (n = o->next); o = n) - { - if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n)) - { - o->next = n->next; - free(n->name); - free(n); - n = o; - } - } - /* hook up backward links */ - prev = NULL; - for (o = output; o; o = o->next) - { - o->prev = prev; - prev = o; - } - return output; -} - -static char * -preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output) -{ - char *preferred_mode = NULL; - - /* Check for a configured preference for a particular mode */ - preferred_mode = xf86GetOptValString (output->options, - OPTION_PREFERRED_MODE); - if (preferred_mode) - return preferred_mode; - - if (pScrn->display->modes && *pScrn->display->modes) - preferred_mode = *pScrn->display->modes; - - return preferred_mode; -} - -static void -GuessRangeFromModes(MonPtr mon, DisplayModePtr mode) -{ - if (!mon || !mode) - return; - - mon->nHsync = 1; - mon->hsync[0].lo = 1024.0; - mon->hsync[0].hi = 0.0; - - mon->nVrefresh = 1; - mon->vrefresh[0].lo = 1024.0; - mon->vrefresh[0].hi = 0.0; - - while (mode) { - if (!mode->HSync) - mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal); - - if (!mode->VRefresh) - mode->VRefresh = (1000.0 * ((float) mode->Clock)) / - ((float) (mode->HTotal * mode->VTotal)); - - if (mode->HSync < mon->hsync[0].lo) - mon->hsync[0].lo = mode->HSync; - - if (mode->HSync > mon->hsync[0].hi) - mon->hsync[0].hi = mode->HSync; - - if (mode->VRefresh < mon->vrefresh[0].lo) - mon->vrefresh[0].lo = mode->VRefresh; - - if (mode->VRefresh > mon->vrefresh[0].hi) - mon->vrefresh[0].hi = mode->VRefresh; - - mode = mode->next; - } - - /* stretch out the bottom to fit 640x480@60 */ - if (mon->hsync[0].lo > 31.0) - mon->hsync[0].lo = 31.0; - if (mon->vrefresh[0].lo > 58.0) - mon->vrefresh[0].lo = 58.0; -} - -enum det_monrec_source { - sync_config, sync_edid, sync_default -}; - -struct det_monrec_parameter { - MonRec *mon_rec; - int *max_clock; - Bool set_hsync; - Bool set_vrefresh; - enum det_monrec_source *sync_source; -}; - -static void handle_detailed_monrec(struct detailed_monitor_section *det_mon, - void *data) -{ - struct det_monrec_parameter *p; - p = (struct det_monrec_parameter *)data; - - if (det_mon->type == DS_RANGES) { - struct monitor_ranges *ranges = &det_mon->section.ranges; - if (p->set_hsync && ranges->max_h) { - p->mon_rec->hsync[p->mon_rec->nHsync].lo = ranges->min_h; - p->mon_rec->hsync[p->mon_rec->nHsync].hi = ranges->max_h; - p->mon_rec->nHsync++; - if (*p->sync_source == sync_default) - *p->sync_source = sync_edid; - } - if (p->set_vrefresh && ranges->max_v) { - p->mon_rec->vrefresh[p->mon_rec->nVrefresh].lo = ranges->min_v; - p->mon_rec->vrefresh[p->mon_rec->nVrefresh].hi = ranges->max_v; - p->mon_rec->nVrefresh++; - if (*p->sync_source == sync_default) - *p->sync_source = sync_edid; - } - if (ranges->max_clock * 1000 > *p->max_clock) - *p->max_clock = ranges->max_clock * 1000; - } -} - -void -xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int o; - - /* When canGrow was TRUE in the initial configuration we have to - * compare against the maximum values so that we don't drop modes. - * When canGrow was FALSE, the maximum values would have been clamped - * anyway. - */ - if (maxX == 0 || maxY == 0) { - maxX = config->maxWidth; - maxY = config->maxHeight; - } - - /* Probe the list of modes for each output. */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - DisplayModePtr mode; - DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL; - char *preferred_mode; - xf86MonPtr edid_monitor; - XF86ConfMonitorPtr conf_monitor; - MonRec mon_rec; - int min_clock = 0; - int max_clock = 0; - double clock; - Bool add_default_modes = xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE); - Bool debug_modes = config->debug_modes || - xf86Initialising; - enum det_monrec_source sync_source = sync_default; - - while (output->probed_modes != NULL) - xf86DeleteMode(&output->probed_modes, output->probed_modes); - - /* - * Check connection status - */ - output->status = (*output->funcs->detect)(output); - - if (output->status == XF86OutputStatusDisconnected && - !xf86ReturnOptValBool(output->options, OPTION_ENABLE, FALSE)) - { - xf86OutputSetEDID (output, NULL); - continue; - } - - memset (&mon_rec, '\0', sizeof (mon_rec)); - - conf_monitor = output->conf_monitor; - - if (conf_monitor) - { - int i; - - for (i = 0; i < conf_monitor->mon_n_hsync; i++) - { - mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo; - mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi; - mon_rec.nHsync++; - sync_source = sync_config; - } - for (i = 0; i < conf_monitor->mon_n_vrefresh; i++) - { - mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo; - mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi; - mon_rec.nVrefresh++; - sync_source = sync_config; - } - config_modes = xf86GetMonitorModes (scrn, conf_monitor); - } - - output_modes = (*output->funcs->get_modes) (output); - - edid_monitor = output->MonInfo; - - if (edid_monitor) - { - struct det_monrec_parameter p; - struct disp_features *features = &edid_monitor->features; - - /* if display is not continuous-frequency, don't add default modes */ - if (!GTF_SUPPORTED(features->msc)) - add_default_modes = FALSE; - - p.mon_rec = &mon_rec; - p.max_clock = &max_clock; - p.set_hsync = mon_rec.nHsync == 0; - p.set_vrefresh = mon_rec.nVrefresh == 0; - p.sync_source = &sync_source; - - xf86ForEachDetailedBlock(edid_monitor, - handle_detailed_monrec, - &p); - } - - if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK, - OPTUNITS_KHZ, &clock)) - min_clock = (int) clock; - if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK, - OPTUNITS_KHZ, &clock)) - max_clock = (int) clock; - - /* If we still don't have a sync range, guess wildly */ - if (!mon_rec.nHsync || !mon_rec.nVrefresh) - GuessRangeFromModes(&mon_rec, output_modes); - - /* - * These limits will end up setting a 1024x768@60Hz mode by default, - * which seems like a fairly good mode to use when nothing else is - * specified - */ - if (mon_rec.nHsync == 0) - { - mon_rec.hsync[0].lo = 31.0; - mon_rec.hsync[0].hi = 55.0; - mon_rec.nHsync = 1; - } - if (mon_rec.nVrefresh == 0) - { - mon_rec.vrefresh[0].lo = 58.0; - mon_rec.vrefresh[0].hi = 62.0; - mon_rec.nVrefresh = 1; - } - - if (add_default_modes) - default_modes = xf86GetDefaultModes (); - - /* - * If this is not an RB monitor, remove RB modes from the default - * pool. RB modes from the config or the monitor itself are fine. - */ - if (!mon_rec.reducedblanking) - xf86ValidateModesReducedBlanking (scrn, default_modes); - - if (sync_source == sync_config) - { - /* - * Check output and config modes against sync range from config file - */ - xf86ValidateModesSync (scrn, output_modes, &mon_rec); - xf86ValidateModesSync (scrn, config_modes, &mon_rec); - } - /* - * Check default modes against sync range - */ - xf86ValidateModesSync (scrn, default_modes, &mon_rec); - /* - * Check default modes against monitor max clock - */ - if (max_clock) { - xf86ValidateModesClocks(scrn, default_modes, - &min_clock, &max_clock, 1); - xf86ValidateModesClocks(scrn, output_modes, - &min_clock, &max_clock, 1); - } - - output->probed_modes = NULL; - output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes); - output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes); - output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes); - - /* - * Check all modes against max size, interlace, and doublescan - */ - if (maxX && maxY) - xf86ValidateModesSize (scrn, output->probed_modes, - maxX, maxY, 0); - - { - int flags = (output->interlaceAllowed ? V_INTERLACE : 0) | - (output->doubleScanAllowed ? V_DBLSCAN : 0); - xf86ValidateModesFlags (scrn, output->probed_modes, flags); - } - - /* - * Check all modes against output - */ - for (mode = output->probed_modes; mode != NULL; mode = mode->next) - if (mode->status == MODE_OK) - mode->status = (*output->funcs->mode_valid)(output, mode); - - xf86PruneInvalidModes(scrn, &output->probed_modes, debug_modes); - - output->probed_modes = xf86SortModes (output->probed_modes); - - /* Check for a configured preference for a particular mode */ - preferred_mode = preferredMode(scrn, output); - - if (preferred_mode) - { - for (mode = output->probed_modes; mode; mode = mode->next) - { - if (!strcmp (preferred_mode, mode->name)) - { - if (mode != output->probed_modes) - { - if (mode->prev) - mode->prev->next = mode->next; - if (mode->next) - mode->next->prev = mode->prev; - mode->next = output->probed_modes; - output->probed_modes->prev = mode; - mode->prev = NULL; - output->probed_modes = mode; - } - mode->type |= (M_T_PREFERRED|M_T_USERPREF); - break; - } - } - } - - output->initial_rotation = xf86OutputInitialRotation (output); - - if (debug_modes) { - if (output->probed_modes != NULL) { - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "Printing probed modes for output %s\n", - output->name); - } else { - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "No remaining probed modes for output %s\n", - output->name); - } - } - for (mode = output->probed_modes; mode != NULL; mode = mode->next) - { - /* The code to choose the best mode per pipe later on will require - * VRefresh to be set. - */ - mode->VRefresh = xf86ModeVRefresh(mode); - xf86SetModeCrtc(mode, INTERLACE_HALVE_V); - - if (debug_modes) - xf86PrintModeline(scrn->scrnIndex, mode); - } - } -} - - -/** - * Copy one of the output mode lists to the ScrnInfo record - */ - -/* XXX where does this function belong? Here? */ -void -xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y); - -static DisplayModePtr -biggestMode(DisplayModePtr a, DisplayModePtr b) -{ - int A, B; - - if (!a) - return b; - if (!b) - return a; - - A = a->HDisplay * a->VDisplay; - B = b->HDisplay * b->VDisplay; - - if (A > B) - return a; - - return b; -} - -static xf86OutputPtr -SetCompatOutput(xf86CrtcConfigPtr config) -{ - xf86OutputPtr output = NULL, test = NULL; - DisplayModePtr maxmode = NULL, testmode, mode; - int o, compat = -1, count, mincount = 0; - - /* Look for one that's definitely connected */ - for (o = 0; o < config->num_output; o++) - { - test = config->output[o]; - if (!test->crtc) - continue; - if (test->status != XF86OutputStatusConnected) - continue; - if (!test->probed_modes) - continue; - - testmode = mode = test->probed_modes; - for (count = 0; mode; mode = mode->next, count++) - testmode = biggestMode(testmode, mode); - - if (!output) { - output = test; - compat = o; - maxmode = testmode; - mincount = count; - } else if (maxmode == biggestMode(maxmode, testmode)) { - output = test; - compat = o; - maxmode = testmode; - mincount = count; - } else if ((maxmode->HDisplay == testmode->HDisplay) && - (maxmode->VDisplay == testmode->VDisplay) && - count <= mincount) { - output = test; - compat = o; - maxmode = testmode; - mincount = count; - } - } - - /* If we didn't find one, take anything we can get */ - if (!output) - { - for (o = 0; o < config->num_output; o++) - { - test = config->output[o]; - if (!test->crtc) - continue; - if (!test->probed_modes) - continue; - - if (!output) { - output = test; - compat = o; - } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) { - output = test; - compat = o; - } - } - } - - if (compat >= 0) { - config->compat_output = compat; - } else { - /* Don't change the compat output when no valid outputs found */ - output = config->output[config->compat_output]; - } - - return output; -} - -void -xf86SetScrnInfoModes (ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - xf86OutputPtr output; - xf86CrtcPtr crtc; - DisplayModePtr last, mode = NULL; - - output = SetCompatOutput(config); - - if (!output) - return; /* punt */ - - crtc = output->crtc; - - /* Clear any existing modes from scrn->modes */ - while (scrn->modes != NULL) - xf86DeleteMode(&scrn->modes, scrn->modes); - - /* Set scrn->modes to the mode list for the 'compat' output */ - scrn->modes = xf86DuplicateModes(scrn, output->probed_modes); - - if (crtc) { - for (mode = scrn->modes; mode; mode = mode->next) - if (xf86ModesEqual (mode, &crtc->desiredMode)) - break; - } - - if (scrn->modes != NULL) { - /* For some reason, scrn->modes is circular, unlike the other mode - * lists. How great is that? - */ - for (last = scrn->modes; last && last->next; last = last->next) - ; - last->next = scrn->modes; - scrn->modes->prev = last; - if (mode) { - while (scrn->modes != mode) - scrn->modes = scrn->modes->next; - } - } - scrn->currentMode = scrn->modes; -#ifdef XFreeXDGA - if (scrn->pScreen) - _xf86_di_dga_reinit_internal(scrn->pScreen); -#endif -} - -static Bool -xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, - Bool *enabled) -{ - Bool any_enabled = FALSE; - int o; - - for (o = 0; o < config->num_output; o++) - any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE); - - if (!any_enabled) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "No outputs definitely connected, trying again...\n"); - - for (o = 0; o < config->num_output; o++) - any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], FALSE); - } - - return any_enabled; -} - -static Bool -nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index) -{ - int o = *index; - - for (o++; o < config->num_output; o++) { - if (enabled[o]) { - *index = o; - return TRUE; - } - } - - return FALSE; -} - -static Bool -aspectMatch(float a, float b) -{ - return fabs(1 - (a / b)) < 0.05; -} - -static DisplayModePtr -nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect) -{ - DisplayModePtr m = NULL; - - if (!o) - return NULL; - - if (!last) - m = o->probed_modes; - else - m = last->next; - - for (; m; m = m->next) - if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay)) - return m; - - return NULL; -} - -static DisplayModePtr -bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) -{ - int o = -1, p; - DisplayModePtr mode = NULL, test = NULL, match = NULL; - - if (!nextEnabledOutput(config, enabled, &o)) - return NULL; - while ((mode = nextAspectMode(config->output[o], mode, aspect))) { - test = mode; - for (p = o; nextEnabledOutput(config, enabled, &p); ) { - test = xf86OutputFindClosestMode(config->output[p], mode); - if (!test) - break; - if (test->HDisplay != mode->HDisplay || - test->VDisplay != mode->VDisplay) { - test = NULL; - break; - } - } - - /* if we didn't match it on all outputs, try the next one */ - if (!test) - continue; - - /* if it's bigger than the last one, save it */ - if (!match || (test->HDisplay > match->HDisplay)) - match = test; - } - - /* return the biggest one found */ - return match; -} - -static Bool -xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, - DisplayModePtr *modes, Bool *enabled, - int width, int height) -{ - int o, p; - int max_pref_width = 0, max_pref_height = 0; - DisplayModePtr *preferred, *preferred_match; - Bool ret = FALSE; - - preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr)); - preferred_match = xnfcalloc(config->num_output, sizeof(DisplayModePtr)); - - /* Check if the preferred mode is available on all outputs */ - for (p = -1; nextEnabledOutput(config, enabled, &p); ) { - Rotation r = config->output[p]->initial_rotation; - DisplayModePtr mode; - if ((preferred[p] = xf86OutputHasPreferredMode(config->output[p], - width, height))) { - int pref_width = xf86ModeWidth(preferred[p], r); - int pref_height = xf86ModeHeight(preferred[p], r); - Bool all_match = TRUE; - - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - Bool match = FALSE; - xf86OutputPtr output = config->output[o]; - if (o == p) - continue; - - for (mode = output->probed_modes; mode; mode = mode->next) { - Rotation r = output->initial_rotation; - if (xf86ModeWidth(mode, r) == pref_width && - xf86ModeHeight(mode, r) == pref_height) { - preferred[o] = mode; - match = TRUE; - } - } - - all_match &= match; - } - - if (all_match && - (pref_width*pref_height > max_pref_width*max_pref_height)) { - for (o = -1; nextEnabledOutput(config, enabled, &o); ) - preferred_match[o] = preferred[o]; - max_pref_width = pref_width; - max_pref_height = pref_height; - ret = TRUE; - } - } - } - - /* - * If there's no preferred mode, but only one monitor, pick the - * biggest mode for its aspect ratio, assuming one exists. - */ - if (!ret) do { - int i = 0; - float aspect = 0.0; - - /* count the number of enabled outputs */ - for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ; - - if (i != 1) - break; - - p = -1; - nextEnabledOutput(config, enabled, &p); - if (config->output[p]->mm_height) - aspect = (float)config->output[p]->mm_width / - (float)config->output[p]->mm_height; - - if (aspect) - preferred_match[p] = bestModeForAspect(config, enabled, aspect); - - if (preferred_match[p]) - ret = TRUE; - - } while (0); - - if (ret) { - /* oh good, there is a match. stash the selected modes and return. */ - memcpy(modes, preferred_match, - config->num_output * sizeof(DisplayModePtr)); - } - - free(preferred); - free(preferred_match); - return ret; -} - -static Bool -xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, - DisplayModePtr *modes, Bool *enabled, - int width, int height) -{ - int o; - float aspect = 0.0, *aspects; - xf86OutputPtr output; - Bool ret = FALSE; - DisplayModePtr guess = NULL, aspect_guess = NULL, base_guess = NULL; - - aspects = xnfcalloc(config->num_output, sizeof(float)); - - /* collect the aspect ratios */ - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - output = config->output[o]; - if (output->mm_height) - aspects[o] = (float)output->mm_width / (float)output->mm_height; - else - aspects[o] = 4.0 / 3.0; - } - - /* check that they're all the same */ - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - output = config->output[o]; - if (!aspect) { - aspect = aspects[o]; - } else if (!aspectMatch(aspect, aspects[o])) { - goto no_aspect_match; - } - } - - /* if they're all 4:3, just skip ahead and save effort */ - if (!aspectMatch(aspect, 4.0/3.0)) - aspect_guess = bestModeForAspect(config, enabled, aspect); - -no_aspect_match: - base_guess = bestModeForAspect(config, enabled, 4.0/3.0); - - guess = biggestMode(base_guess, aspect_guess); - - if (!guess) - goto out; - - /* found a mode that works everywhere, now apply it */ - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - modes[o] = xf86OutputFindClosestMode(config->output[o], guess); - } - ret = TRUE; - -out: - free(aspects); - return ret; -} - -static Bool -xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, - DisplayModePtr *modes, Bool *enabled, - int width, int height) -{ - DisplayModePtr target_mode = NULL; - Rotation target_rotation = RR_Rotate_0; - DisplayModePtr default_mode; - int default_preferred, target_preferred = 0, o; - - /* User preferred > preferred > other modes */ - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - default_mode = xf86DefaultMode (config->output[o], width, height); - if (!default_mode) - continue; - - default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) + - ((default_mode->type & M_T_USERPREF) != 0)); - - if (default_preferred > target_preferred || !target_mode) { - target_mode = default_mode; - target_preferred = default_preferred; - target_rotation = config->output[o]->initial_rotation; - config->compat_output = o; - } - } - - if (target_mode) - modes[config->compat_output] = target_mode; - - /* Fill in other output modes */ - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - if (!modes[o]) - modes[o] = xf86ClosestMode(config->output[o], target_mode, - target_rotation, width, height); - } - - return target_mode != NULL; -} - -static Bool -xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, - DisplayModePtr *modes, Bool *enabled, - int width, int height) -{ - int o; - - if (xf86UserConfiguredOutputs(scrn, modes)) - return xf86TargetFallback(scrn, config, modes, enabled, width, height); - - for (o = -1; nextEnabledOutput(config, enabled, &o); ) - if (xf86OutputHasUserPreferredMode(config->output[o])) - return - xf86TargetFallback(scrn, config, modes, enabled, width, height); - - return FALSE; -} - -static Bool -xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green, - float gamma_blue) -{ - int i, size = 256; - CARD16 *red, *green, *blue; - - red = malloc(3 * size * sizeof(CARD16)); - green = red + size; - blue = green + size; - - /* Only cause warning if user wanted gamma to be set. */ - if (!crtc->funcs->gamma_set && (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) { - free(red); - return FALSE; - } else if (!crtc->funcs->gamma_set) { - free(red); - return TRUE; - } - - /* At this early stage none of the randr-interface stuff is up. - * So take the default gamma size for lack of something better. - */ - for (i = 0; i < size; i++) { - if (gamma_red == 1.0) - red[i] = i << 8; - else - red[i] = (CARD16)(pow((double)i/(double)(size - 1), - 1. / (double)gamma_red) * (double)(size - 1) * 256); - - if (gamma_green == 1.0) - green[i] = i << 8; - else - green[i] = (CARD16)(pow((double)i/(double)(size - 1), - 1. / (double)gamma_green) * (double)(size - 1) * 256); - - if (gamma_blue == 1.0) - blue[i] = i << 8; - else - blue[i] = (CARD16)(pow((double)i/(double)(size - 1), - 1. / (double)gamma_blue) * (double)(size - 1) * 256); - } - - /* Default size is 256, so anything else is failure. */ - if (size != crtc->gamma_size) { - free(red); - return FALSE; - } - - crtc->gamma_size = size; - memcpy (crtc->gamma_red, red, crtc->gamma_size * sizeof (CARD16)); - memcpy (crtc->gamma_green, green, crtc->gamma_size * sizeof (CARD16)); - memcpy (crtc->gamma_blue, blue, crtc->gamma_size * sizeof (CARD16)); - - /* Do not set gamma now, delay until the crtc is activated. */ - - free(red); - - return TRUE; -} - -static Bool -xf86OutputSetInitialGamma(xf86OutputPtr output) -{ - XF86ConfMonitorPtr mon = output->conf_monitor; - float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0; - - if (!mon) - return TRUE; - - if (!output->crtc) - return FALSE; - - /* Get configured values, where they exist. */ - if (mon->mon_gamma_red >= GAMMA_MIN && - mon->mon_gamma_red <= GAMMA_MAX) - gamma_red = mon->mon_gamma_red; - - if (mon->mon_gamma_green >= GAMMA_MIN && - mon->mon_gamma_green <= GAMMA_MAX) - gamma_green = mon->mon_gamma_green; - - if (mon->mon_gamma_blue >= GAMMA_MIN && - mon->mon_gamma_blue <= GAMMA_MAX) - gamma_blue = mon->mon_gamma_blue; - - /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */ - if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) { - xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n", output->name, gamma_red, gamma_green, gamma_blue); - return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green, gamma_blue); - }else - return TRUE; -} - -/** - * Construct default screen configuration - * - * Given auto-detected (and, eventually, configured) values, - * construct a usable configuration for the system - * - * canGrow indicates that the driver can resize the screen to larger than its - * initially configured size via the config->funcs->resize hook. If TRUE, this - * function will set virtualX and virtualY to match the initial configuration - * and leave config->max{Width,Height} alone. If FALSE, it will bloat - * virtual[XY] to include the largest modes and set config->max{Width,Height} - * accordingly. - */ - -Bool -xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int o, c; - xf86CrtcPtr *crtcs; - DisplayModePtr *modes; - Bool *enabled; - int width, height; - int i = scrn->scrnIndex; - Bool have_outputs = TRUE; - Bool ret; - - /* Set up the device options */ - config->options = xnfalloc (sizeof (xf86DeviceOptions)); - memcpy (config->options, xf86DeviceOptions, sizeof (xf86DeviceOptions)); - xf86ProcessOptions (scrn->scrnIndex, - scrn->options, - config->options); - config->debug_modes = xf86ReturnOptValBool (config->options, - OPTION_MODEDEBUG, FALSE); - - if (scrn->display->virtualX) - width = scrn->display->virtualX; - else - width = config->maxWidth; - if (scrn->display->virtualY) - height = scrn->display->virtualY; - else - height = config->maxHeight; - - xf86ProbeOutputModes (scrn, width, height); - - crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr)); - modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr)); - enabled = xnfcalloc (config->num_output, sizeof (Bool)); - - ret = xf86CollectEnabledOutputs(scrn, config, enabled); - if (ret == FALSE && canGrow) { - xf86DrvMsg(i, X_WARNING, "Unable to find connected outputs - setting %dx%d initial framebuffer\n", - NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT); - have_outputs = FALSE; - } else { - if (xf86TargetUserpref(scrn, config, modes, enabled, width, height)) - xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n"); - else if (xf86TargetPreferred(scrn, config, modes, enabled, width, height)) - xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n"); - else if (xf86TargetAspect(scrn, config, modes, enabled, width, height)) - xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n"); - else if (xf86TargetFallback(scrn, config, modes, enabled, width, height)) - xf86DrvMsg(i, X_INFO, "Using sloppy heuristic for initial modes\n"); - else - xf86DrvMsg(i, X_WARNING, "Unable to find initial modes\n"); - } - - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - if (!modes[o]) - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Output %s enabled but has no modes\n", - config->output[o]->name); - else - xf86DrvMsg (scrn->scrnIndex, X_INFO, - "Output %s using initial mode %s\n", - config->output[o]->name, modes[o]->name); - } - - /* - * Set the position of each output - */ - if (!xf86InitialOutputPositions (scrn, modes)) - { - free(crtcs); - free(modes); - return FALSE; - } - - /* - * Set initial panning of each output - */ - xf86InitialPanning (scrn); - - /* - * Assign CRTCs to fit output configuration - */ - if (have_outputs && !xf86PickCrtcs (scrn, crtcs, modes, 0, width, height)) - { - free(crtcs); - free(modes); - return FALSE; - } - - /* XXX override xf86 common frame computation code */ - - scrn->display->frameX0 = 0; - scrn->display->frameY0 = 0; - - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - - crtc->enabled = FALSE; - memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode)); - /* Set default gamma for all crtc's. */ - /* This is done to avoid problems later on with cloned outputs. */ - xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0); - } - - if (xf86_crtc_supports_gamma(scrn)) - xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n"); - - /* - * Set initial configuration - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - DisplayModePtr mode = modes[o]; - xf86CrtcPtr crtc = crtcs[o]; - - if (mode && crtc) - { - crtc->desiredMode = *mode; - crtc->desiredRotation = output->initial_rotation; - crtc->desiredX = output->initial_x; - crtc->desiredY = output->initial_y; - crtc->desiredTransformPresent = FALSE; - crtc->enabled = TRUE; - memcpy (&crtc->panningTotalArea, &output->initialTotalArea, sizeof(BoxRec)); - memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec)); - memcpy (crtc->panningBorder, output->initialBorder, 4*sizeof(INT16)); - output->crtc = crtc; - if (!xf86OutputSetInitialGamma(output)) - xf86DrvMsg (scrn->scrnIndex, X_WARNING, "Initial gamma correction for output %s: failed.\n", output->name); - } else { - output->crtc = NULL; - } - } - - if (scrn->display->virtualX == 0) - { - /* - * Expand virtual size to cover the current config and potential mode - * switches, if the driver can't enlarge the screen later. - */ - xf86DefaultScreenLimits (scrn, &width, &height, canGrow); - - if (have_outputs == FALSE) { - if (width < NO_OUTPUT_DEFAULT_WIDTH && height < NO_OUTPUT_DEFAULT_HEIGHT) { - width = NO_OUTPUT_DEFAULT_WIDTH; - height = NO_OUTPUT_DEFAULT_HEIGHT; - } - } - - scrn->display->virtualX = width; - scrn->display->virtualY = height; - } - - if (width > scrn->virtualX) - scrn->virtualX = width; - if (height > scrn->virtualY) - scrn->virtualY = height; - - /* - * Make sure the configuration isn't too small. - */ - if (width < config->minWidth || height < config->minHeight) - return FALSE; - - /* - * Limit the crtc config to virtual[XY] if the driver can't grow the - * desktop. - */ - if (!canGrow) - { - xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight, - width, height); - } - - if (have_outputs) { - /* Mirror output modes to scrn mode list */ - xf86SetScrnInfoModes (scrn); - } else { - /* Clear any existing modes from scrn->modes */ - while (scrn->modes != NULL) - xf86DeleteMode(&scrn->modes, scrn->modes); - scrn->modes = xf86ModesAdd(scrn->modes, - xf86CVTMode(width, height, 60, 0, 0)); - } - - - free(crtcs); - free(modes); - return TRUE; -} - -/* - * Check the CRTC we're going to map each output to vs. it's current - * CRTC. If they don't match, we have to disable the output and the CRTC - * since the driver will have to re-route things. - */ -static void -xf86PrepareOutputs (ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int o; - - for (o = 0; o < config->num_output; o++) { - xf86OutputPtr output = config->output[o]; -#if RANDR_GET_CRTC_INTERFACE - /* Disable outputs that are unused or will be re-routed */ - if (!output->funcs->get_crtc || - output->crtc != (*output->funcs->get_crtc)(output) || - output->crtc == NULL) -#endif - (*output->funcs->dpms)(output, DPMSModeOff); - } -} - -static void -xf86PrepareCrtcs (ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - for (c = 0; c < config->num_crtc; c++) { -#if RANDR_GET_CRTC_INTERFACE - xf86CrtcPtr crtc = config->crtc[c]; - xf86OutputPtr output = NULL; - uint32_t desired_outputs = 0, current_outputs = 0; - int o; - - for (o = 0; o < config->num_output; o++) { - output = config->output[o]; - if (output->crtc == crtc) - desired_outputs |= (1<funcs->get_crtc) { - desired_outputs = 0; - break; - } - if ((*output->funcs->get_crtc)(output) == crtc) - current_outputs |= (1<funcs->dpms)(crtc, DPMSModeOff); -#else - (*crtc->funcs->dpms)(crtc, DPMSModeOff); -#endif - } -} - -/* - * Using the desired mode information in each crtc, set - * modes (used in EnterVT functions, or at server startup) - */ - -Bool -xf86SetDesiredModes (ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CrtcPtr crtc = config->crtc[0]; - int c; - - /* A driver with this hook will take care of this */ - if (!crtc->funcs->set_mode_major) { - xf86PrepareOutputs(scrn); - xf86PrepareCrtcs(scrn); - } - - for (c = 0; c < config->num_crtc; c++) - { - xf86OutputPtr output = NULL; - xf86CrtcSetRec set; - int o; - RRTransformPtr transform; - - crtc = config->crtc[c]; - - /* Skip disabled CRTCs */ - if (!crtc->enabled) - continue; - - if (xf86CompatOutput(scrn) && xf86CompatCrtc(scrn) == crtc) - output = xf86CompatOutput(scrn); - else - { - for (o = 0; o < config->num_output; o++) - if (config->output[o]->crtc == crtc) - { - output = config->output[o]; - break; - } - } - /* paranoia */ - if (!output) - continue; - - /* Mark that we'll need to re-set the mode for sure */ - memset(&crtc->mode, 0, sizeof(crtc->mode)); - if (!crtc->desiredMode.CrtcHDisplay) - { - DisplayModePtr mode = xf86OutputFindClosestMode (output, scrn->currentMode); - - if (!mode) - return FALSE; - crtc->desiredMode = *mode; - crtc->desiredRotation = RR_Rotate_0; - crtc->desiredTransformPresent = FALSE; - crtc->desiredX = 0; - crtc->desiredY = 0; - } - - if (crtc->desiredTransformPresent) - transform = &crtc->desiredTransform; - else - transform = NULL; - set.mode = &crtc->desiredMode; - set.rotation = crtc->desiredRotation; - set.transform = transform; - set.x = crtc->desiredX; - set.y = crtc->desiredY; - set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput | - XF86CrtcSetOrigin | XF86CrtcSetTransform | - XF86CrtcSetRotation); - if (!xf86CrtcSet(crtc, &set)) - return FALSE; - } - - xf86DisableUnusedFunctions(scrn); - return TRUE; -} - -/** - * In the current world order, there are lists of modes per output, which may - * or may not include the mode that was asked to be set by XFree86's mode - * selection. Find the closest one, in the following preference order: - * - * - Equality - * - Closer in size to the requested mode, but no larger - * - Closer in refresh rate to the requested mode. - */ - -DisplayModePtr -xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired) -{ - DisplayModePtr best = NULL, scan = NULL; - - for (scan = output->probed_modes; scan != NULL; scan = scan->next) - { - /* If there's an exact match, we're done. */ - if (xf86ModesEqual(scan, desired)) { - best = desired; - break; - } - - /* Reject if it's larger than the desired mode. */ - if (scan->HDisplay > desired->HDisplay || - scan->VDisplay > desired->VDisplay) - { - continue; - } - - /* - * If we haven't picked a best mode yet, use the first - * one in the size range - */ - if (best == NULL) - { - best = scan; - continue; - } - - /* Find if it's closer to the right size than the current best - * option. - */ - if ((scan->HDisplay > best->HDisplay && - scan->VDisplay >= best->VDisplay) || - (scan->HDisplay >= best->HDisplay && - scan->VDisplay > best->VDisplay)) - { - best = scan; - continue; - } - - /* Find if it's still closer to the right refresh than the current - * best resolution. - */ - if (scan->HDisplay == best->HDisplay && - scan->VDisplay == best->VDisplay && - (fabs(scan->VRefresh - desired->VRefresh) < - fabs(best->VRefresh - desired->VRefresh))) { - best = scan; - } - } - return best; -} - -/** - * When setting a mode through XFree86-VidModeExtension or XFree86-DGA, - * take the specified mode and apply it to the crtc connected to the compat - * output. Then, find similar modes for the other outputs, as with the - * InitialConfiguration code above. The goal is to clone the desired - * mode across all outputs that are currently active. - */ - -Bool -xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - Bool ok = TRUE; - xf86OutputPtr compat_output; - DisplayModePtr compat_mode = NULL; - int c; - - /* - * Let the compat output drive the final mode selection - */ - compat_output = xf86CompatOutput(pScrn); - if (compat_output) - compat_mode = xf86OutputFindClosestMode (compat_output, desired); - if (compat_mode) - desired = compat_mode; - - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - DisplayModePtr crtc_mode = NULL; - int o; - xf86CrtcSetRec set; - - if (!crtc->enabled) - continue; - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - DisplayModePtr output_mode; - - /* skip outputs not on this crtc */ - if (output->crtc != crtc) - continue; - - if (crtc_mode) - { - output_mode = xf86OutputFindClosestMode (output, crtc_mode); - if (output_mode != crtc_mode) - output->crtc = NULL; - } - else - crtc_mode = xf86OutputFindClosestMode (output, desired); - } - if (!crtc_mode) - { - crtc->enabled = FALSE; - continue; - } - set.mode = crtc_mode; - set.rotation = rotation; - set.transform = NULL; - set.x = 0; - set.y = 0; - set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput | - XF86CrtcSetOrigin | XF86CrtcSetTransform | - XF86CrtcSetRotation); - if (!xf86CrtcSet (crtc, &set)) - ok = FALSE; - else - { - crtc->desiredMode = *crtc_mode; - crtc->desiredRotation = rotation; - crtc->desiredTransformPresent = FALSE; - crtc->desiredX = 0; - crtc->desiredY = 0; - } - } - xf86DisableUnusedFunctions(pScrn); -#ifdef RANDR_12_INTERFACE - xf86RandR12TellChanged (pScrn->pScreen); -#endif - return ok; -} - - -/** - * Set the DPMS power mode of all outputs and CRTCs. - * - * If the new mode is off, it will turn off outputs and then CRTCs. - * Otherwise, it will affect CRTCs before outputs. - */ -void -xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int i; - - if (!scrn->vtSema) - return; - - if (mode == DPMSModeOff) { - for (i = 0; i < config->num_output; i++) { - xf86OutputPtr output = config->output[i]; - if (output->crtc != NULL) - (*output->funcs->dpms) (output, mode); - } - } - - for (i = 0; i < config->num_crtc; i++) { - xf86CrtcPtr crtc = config->crtc[i]; - if (crtc->enabled) - (*crtc->funcs->dpms) (crtc, mode); - } - - if (mode != DPMSModeOff) { - for (i = 0; i < config->num_output; i++) { - xf86OutputPtr output = config->output[i]; - if (output->crtc != NULL) - (*output->funcs->dpms) (output, mode); - } - } -} - -/** - * Implement the screensaver by just calling down into the driver DPMS hooks. - * - * Even for monitors with no DPMS support, by the definition of our DPMS hooks, - * the outputs will still get disabled (blanked). - */ -Bool -xf86SaveScreen(ScreenPtr pScreen, int mode) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - - if (xf86IsUnblank(mode)) - xf86DPMSSet(pScrn, DPMSModeOn, 0); - else - xf86DPMSSet(pScrn, DPMSModeOff, 0); - - return TRUE; -} - -/** - * Disable all inactive crtcs and outputs - */ -void -xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int o, c; - - for (o = 0; o < xf86_config->num_output; o++) - { - xf86OutputPtr output = xf86_config->output[o]; - if (!output->crtc) - (*output->funcs->dpms)(output, DPMSModeOff); - } - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (!crtc->enabled) - { - crtc->funcs->dpms(crtc, DPMSModeOff); - memset(&crtc->mode, 0, sizeof(crtc->mode)); - xf86RotateDestroy(crtc); - crtc->active = FALSE; - } - } - if (pScrn->pScreen) - xf86_crtc_notify(pScrn->pScreen); - if (pScrn->ModeSet) - pScrn->ModeSet(pScrn); -} - -#ifdef RANDR_12_INTERFACE - -#define EDID_ATOM_NAME "EDID" - -/** - * Set the RandR EDID property - */ -static void -xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len) -{ - Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME) - 1, TRUE); - - /* This may get called before the RandR resources have been created */ - if (output->randr_output == NULL) - return; - - if (data_len != 0) { - RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8, - PropModeReplace, data_len, data, FALSE, TRUE); - } else { - RRDeleteOutputProperty(output->randr_output, edid_atom); - } -} - -#endif - -/* Pull out a phyiscal size from a detailed timing if available. */ -struct det_phySize_parameter { - xf86OutputPtr output; - ddc_quirk_t quirks; - Bool ret; -}; - -static void handle_detailed_physical_size(struct detailed_monitor_section - *det_mon, void *data) -{ - struct det_phySize_parameter *p; - p = (struct det_phySize_parameter *)data; - - if (p->ret == TRUE ) - return ; - - xf86DetTimingApplyQuirks(det_mon, p->quirks, - p->output->MonInfo->features.hsize, - p->output->MonInfo->features.vsize); - if (det_mon->type == DT && - det_mon->section.d_timings.h_size != 0 && - det_mon->section.d_timings.v_size != 0) { - - p->output->mm_width = det_mon->section.d_timings.h_size; - p->output->mm_height = det_mon->section.d_timings.v_size; - p->ret = TRUE; - } -} - -/** - * Set the EDID information for the specified output - */ -void -xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) -{ - ScrnInfoPtr scrn = output->scrn; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - Bool debug_modes = config->debug_modes || xf86Initialising; -#ifdef RANDR_12_INTERFACE - int size; -#endif - - free(output->MonInfo); - - output->MonInfo = edid_mon; - output->mm_width = 0; - output->mm_height = 0; - - if (debug_modes) { - xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", - output->name); - xf86PrintEDID(edid_mon); - } - - /* Set the DDC properties for the 'compat' output */ - if (output == xf86CompatOutput(scrn)) - xf86SetDDCproperties(scrn, edid_mon); - -#ifdef RANDR_12_INTERFACE - /* Set the RandR output properties */ - size = 0; - if (edid_mon) - { - if (edid_mon->ver.version == 1) { - size = 128; - if (edid_mon->flags & EDID_COMPLETE_RAWDATA) - size += edid_mon->no_sections * 128; - } else if (edid_mon->ver.version == 2) - size = 256; - } - xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size); -#endif - - if (edid_mon) { - - struct det_phySize_parameter p; - p.output = output; - p.quirks = xf86DDCDetectQuirks(scrn->scrnIndex,edid_mon, FALSE); - p.ret = FALSE; - xf86ForEachDetailedBlock(edid_mon, - handle_detailed_physical_size, &p); - - /* if no mm size is available from a detailed timing, check the max size field */ - if ((!output->mm_width || !output->mm_height) && - (edid_mon->features.hsize && edid_mon->features.vsize)) - { - output->mm_width = edid_mon->features.hsize * 10; - output->mm_height = edid_mon->features.vsize * 10; - } - } -} - -/** - * Return the list of modes supported by the EDID information - * stored in 'output' - */ -DisplayModePtr -xf86OutputGetEDIDModes (xf86OutputPtr output) -{ - ScrnInfoPtr scrn = output->scrn; - xf86MonPtr edid_mon = output->MonInfo; - - if (!edid_mon) - return NULL; - return xf86DDCGetModes(scrn->scrnIndex, edid_mon); -} - -/* maybe we should care about DDC1? meh. */ -xf86MonPtr -xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) -{ - ScrnInfoPtr scrn = output->scrn; - xf86MonPtr mon; - - mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE); - if (mon) - xf86DDCApplyQuirks(scrn->scrnIndex, mon); - - return mon; -} - -static char *_xf86ConnectorNames[] = { - "None", "VGA", "DVI-I", "DVI-D", - "DVI-A", "Composite", "S-Video", - "Component", "LFP", "Proprietary", - "HDMI", "DisplayPort", - }; -char * -xf86ConnectorGetName(xf86ConnectorType connector) -{ - return _xf86ConnectorNames[connector]; -} - -static void -x86_crtc_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) -{ - dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1; - dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2; - dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1; - dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2; - - if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2) - dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; -} - -static void -x86_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) -{ - if (crtc->enabled) { - crtc_box->x1 = crtc->x; - crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation); - crtc_box->y1 = crtc->y; - crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation); - } else - crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; -} - -static int -xf86_crtc_box_area(BoxPtr box) -{ - return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1); -} - -/* - * Return the crtc covering 'box'. If two crtcs cover a portion of - * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc - * with greater coverage - */ - -static xf86CrtcPtr -xf86_covering_crtc(ScrnInfoPtr pScrn, - BoxPtr box, - xf86CrtcPtr desired, - BoxPtr crtc_box_ret) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86CrtcPtr crtc, best_crtc; - int coverage, best_coverage; - int c; - BoxRec crtc_box, cover_box; - - best_crtc = NULL; - best_coverage = 0; - crtc_box_ret->x1 = 0; - crtc_box_ret->x2 = 0; - crtc_box_ret->y1 = 0; - crtc_box_ret->y2 = 0; - for (c = 0; c < xf86_config->num_crtc; c++) { - crtc = xf86_config->crtc[c]; - x86_crtc_box(crtc, &crtc_box); - x86_crtc_box_intersect(&cover_box, &crtc_box, box); - coverage = xf86_crtc_box_area(&cover_box); - if (coverage && crtc == desired) { - *crtc_box_ret = crtc_box; - return crtc; - } else if (coverage > best_coverage) { - *crtc_box_ret = crtc_box; - best_crtc = crtc; - best_coverage = coverage; - } - } - return best_crtc; -} - -/* - * For overlay video, compute the relevant CRTC and - * clip video to that. - * - * returning FALSE means there was a memory failure of some kind, - * not that the video shouldn't be displayed - */ - -Bool -xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn, - xf86CrtcPtr *crtc_ret, - xf86CrtcPtr desired_crtc, - BoxPtr dst, - INT32 *xa, - INT32 *xb, - INT32 *ya, - INT32 *yb, - RegionPtr reg, - INT32 width, - INT32 height) -{ - Bool ret; - RegionRec crtc_region_local; - RegionPtr crtc_region = reg; - - if (crtc_ret) { - BoxRec crtc_box; - xf86CrtcPtr crtc = xf86_covering_crtc(pScrn, dst, - desired_crtc, - &crtc_box); - - if (crtc) { - RegionInit(&crtc_region_local, &crtc_box, 1); - crtc_region = &crtc_region_local; - RegionIntersect(crtc_region, crtc_region, reg); - } - *crtc_ret = crtc; - } - - ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, - crtc_region, width, height); - - if (crtc_region != reg) - RegionUninit(&crtc_region_local); - - return ret; -} - -xf86_crtc_notify_proc_ptr -xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new) -{ - if (xf86CrtcConfigPrivateIndex != -1) - { - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - xf86_crtc_notify_proc_ptr old; - - old = config->xf86_crtc_notify; - config->xf86_crtc_notify = new; - return old; - } - return NULL; -} - -void -xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old) -{ - if (xf86CrtcConfigPrivateIndex != -1) - { - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - - config->xf86_crtc_notify = old; - } -} - -void -xf86_crtc_notify(ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - - if (config->xf86_crtc_notify) - config->xf86_crtc_notify(screen); -} - -Bool -xf86_crtc_supports_gamma(ScrnInfoPtr pScrn) -{ - if (xf86CrtcConfigPrivateIndex != -1) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86CrtcPtr crtc; - - /* for multiple drivers loaded we need this */ - if (!xf86_config) - return FALSE; - if (xf86_config->num_crtc == 0) - return FALSE; - crtc = xf86_config->crtc[0]; - - return crtc->funcs->gamma_set != NULL; - } - - return FALSE; -} +/* + * Copyright © 2006 Keith Packard + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#else +#ifdef HAVE_CONFIG_H +#include +#endif +#endif + +#include +#include +#include + +#include "xf86.h" +#include "xf86DDC.h" +#include "xf86Crtc.h" +#include "xf86Modes.h" +#include "xf86Priv.h" +#include "xf86RandR12.h" +#include "X11/extensions/render.h" +#include "X11/extensions/dpmsconst.h" +#include "X11/Xatom.h" +#include "picturestr.h" + +#include "xf86xv.h" + +#define NO_OUTPUT_DEFAULT_WIDTH 1024 +#define NO_OUTPUT_DEFAULT_HEIGHT 768 +/* + * Initialize xf86CrtcConfig structure + */ + +int xf86CrtcConfigPrivateIndex = -1; + +void +xf86CrtcConfigInit (ScrnInfoPtr scrn, + const xf86CrtcConfigFuncsRec *funcs) +{ + xf86CrtcConfigPtr config; + + if (xf86CrtcConfigPrivateIndex == -1) + xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); + config = xnfcalloc (1, sizeof (xf86CrtcConfigRec)); + + config->funcs = funcs; + + scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config; +} + +void +xf86CrtcSetSizeRange (ScrnInfoPtr scrn, + int minWidth, int minHeight, + int maxWidth, int maxHeight) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + + config->minWidth = minWidth; + config->minHeight = minHeight; + config->maxWidth = maxWidth; + config->maxHeight = maxHeight; +} + +/* + * Crtc functions + */ +xf86CrtcPtr +xf86CrtcCreate (ScrnInfoPtr scrn, + const xf86CrtcFuncsRec *funcs) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CrtcPtr crtc, *crtcs; + + crtc = calloc(sizeof (xf86CrtcRec), 1); + if (!crtc) + return NULL; + crtc->version = XF86_CRTC_VERSION; + crtc->scrn = scrn; + crtc->funcs = funcs; +#ifdef RANDR_12_INTERFACE + crtc->randr_crtc = NULL; +#endif + crtc->rotation = RR_Rotate_0; + crtc->desiredRotation = RR_Rotate_0; + pixman_transform_init_identity (&crtc->crtc_to_framebuffer); + pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer); + pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc); + crtc->filter = NULL; + crtc->params = NULL; + crtc->nparams = 0; + crtc->filter_width = 0; + crtc->filter_height = 0; + crtc->transform_in_use = FALSE; + crtc->transformPresent = FALSE; + crtc->desiredTransformPresent = FALSE; + memset (&crtc->bounds, '\0', sizeof (crtc->bounds)); + + /* Preallocate gamma at a sensible size. */ + crtc->gamma_size = 256; + crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof (CARD16)); + if (!crtc->gamma_red) { + free(crtc); + return NULL; + } + crtc->gamma_green = crtc->gamma_red + crtc->gamma_size; + crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size; + + if (xf86_config->crtc) + crtcs = realloc(xf86_config->crtc, + (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr)); + else + crtcs = malloc((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr)); + if (!crtcs) + { + free(crtc); + return NULL; + } + xf86_config->crtc = crtcs; + xf86_config->crtc[xf86_config->num_crtc++] = crtc; + return crtc; +} + +void +xf86CrtcDestroy (xf86CrtcPtr crtc) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + int c; + + (*crtc->funcs->destroy) (crtc); + for (c = 0; c < xf86_config->num_crtc; c++) + if (xf86_config->crtc[c] == crtc) + { + memmove (&xf86_config->crtc[c], + &xf86_config->crtc[c+1], + ((xf86_config->num_crtc - (c + 1)) * sizeof(void*))); + xf86_config->num_crtc--; + break; + } + free(crtc->params); + free(crtc->gamma_red); + free(crtc); +} + + +/** + * Return whether any outputs are connected to the specified pipe + */ + +Bool +xf86CrtcInUse (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int o; + + for (o = 0; o < xf86_config->num_output; o++) + if (xf86_config->output[o]->crtc == crtc) + return TRUE; + return FALSE; +} + +void +xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen) +{ + int subpixel_order = SubPixelUnknown; + Bool has_none = FALSE; + ScrnInfoPtr scrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c, o; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + for (o = 0; o < xf86_config->num_output; o++) + { + xf86OutputPtr output = xf86_config->output[o]; + + if (output->crtc == crtc) + { + switch (output->subpixel_order) { + case SubPixelNone: + has_none = TRUE; + break; + case SubPixelUnknown: + break; + default: + subpixel_order = output->subpixel_order; + break; + } + } + if (subpixel_order != SubPixelUnknown) + break; + } + if (subpixel_order != SubPixelUnknown) + { + static const int circle[4] = { + SubPixelHorizontalRGB, + SubPixelVerticalRGB, + SubPixelHorizontalBGR, + SubPixelVerticalBGR, + }; + int rotate; + int c; + for (rotate = 0; rotate < 4; rotate++) + if (crtc->rotation & (1 << rotate)) + break; + for (c = 0; c < 4; c++) + if (circle[c] == subpixel_order) + break; + c = (c + rotate) & 0x3; + if ((crtc->rotation & RR_Reflect_X) && !(c & 1)) + c ^= 2; + if ((crtc->rotation & RR_Reflect_Y) && (c & 1)) + c ^= 2; + subpixel_order = circle[c]; + break; + } + } + if (subpixel_order == SubPixelUnknown && has_none) + subpixel_order = SubPixelNone; + PictureSetSubpixelOrder (pScreen, subpixel_order); +} + +/** + * Sets the given video mode on the given crtc + */ +Bool +xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + RRTransformPtr transform, int x, int y) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int i; + Bool ret = FALSE; + Bool didLock = FALSE; + DisplayModePtr adjusted_mode; + DisplayModeRec saved_mode; + int saved_x, saved_y; + Rotation saved_rotation; + RRTransformRec saved_transform; + Bool saved_transform_present; + + crtc->enabled = xf86CrtcInUse (crtc); + + /* We only hit this if someone explicitly sends a "disabled" modeset. */ + if (!crtc->enabled) + { + /* Check everything for stuff that should be off. */ + xf86DisableUnusedFunctions(scrn); + return TRUE; + } + + adjusted_mode = xf86DuplicateMode(mode); + + + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + if (crtc->transformPresent) { + RRTransformInit (&saved_transform); + RRTransformCopy (&saved_transform, &crtc->transform); + } + saved_transform_present = crtc->transformPresent; + + /* Update crtc values up front so the driver can rely on them for mode + * setting. + */ + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; + if (transform) { + RRTransformCopy (&crtc->transform, transform); + crtc->transformPresent = TRUE; + } else + crtc->transformPresent = FALSE; + + if (crtc->funcs->set_mode_major) { + ret = crtc->funcs->set_mode_major(crtc, mode, rotation, x, y); + goto done; + } + + didLock = crtc->funcs->lock (crtc); + /* Pass our mode to the outputs and the CRTC to give them a chance to + * adjust it according to limitations or output properties, and also + * a chance to reject the mode entirely. + */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if (output->crtc != crtc) + continue; + + if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) { + goto done; + } + } + + if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) { + goto done; + } + + if (!xf86CrtcRotate (crtc)) + goto done; + + /* Prepare the outputs and CRTCs before setting the mode. */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if (output->crtc != crtc) + continue; + + /* Disable the output as the first thing we do. */ + output->funcs->prepare(output); + } + + crtc->funcs->prepare(crtc); + + /* Set up the DPLL and any output state that needs to adjust or depend + * on the DPLL. + */ + crtc->funcs->mode_set(crtc, mode, adjusted_mode, crtc->x, crtc->y); + for (i = 0; i < xf86_config->num_output; i++) + { + xf86OutputPtr output = xf86_config->output[i]; + if (output->crtc == crtc) + output->funcs->mode_set(output, mode, adjusted_mode); + } + + /* Only upload when needed, to avoid unneeded delays. */ + if (!crtc->active && crtc->funcs->gamma_set) + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); + + /* Now, enable the clocks, plane, pipe, and outputs that we set up. */ + crtc->funcs->commit(crtc); + for (i = 0; i < xf86_config->num_output; i++) + { + xf86OutputPtr output = xf86_config->output[i]; + if (output->crtc == crtc) + output->funcs->commit(output); + } + + ret = TRUE; + +done: + if (ret) { + crtc->active = TRUE; + if (scrn->pScreen) + xf86CrtcSetScreenSubpixelOrder (scrn->pScreen); + if (scrn->ModeSet) + scrn->ModeSet(scrn); + } else { + crtc->x = saved_x; + crtc->y = saved_y; + crtc->rotation = saved_rotation; + crtc->mode = saved_mode; + if (saved_transform_present) + RRTransformCopy (&crtc->transform, &saved_transform); + crtc->transformPresent = saved_transform_present; + } + + free(adjusted_mode->name); + free(adjusted_mode); + + if (didLock) + crtc->funcs->unlock (crtc); + + return ret; +} + +/** + * Sets the given video mode on the given crtc, but without providing + * a transform + */ +Bool +xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y) +{ + return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y); +} + +/** + * Pans the screen, does not change the mode + */ +void +xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr scrn = crtc->scrn; + + crtc->x = x; + crtc->y = y; + if (crtc->funcs->set_origin) { + if (!xf86CrtcRotate (crtc)) + return; + crtc->funcs->set_origin (crtc, x, y); + if (scrn->ModeSet) + scrn->ModeSet(scrn); + } + else + xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y); +} + +/* + * Output functions + */ + +extern XF86ConfigPtr xf86configptr; + +typedef enum { + OPTION_PREFERRED_MODE, + OPTION_POSITION, + OPTION_BELOW, + OPTION_RIGHT_OF, + OPTION_ABOVE, + OPTION_LEFT_OF, + OPTION_ENABLE, + OPTION_DISABLE, + OPTION_MIN_CLOCK, + OPTION_MAX_CLOCK, + OPTION_IGNORE, + OPTION_ROTATE, + OPTION_PANNING, + OPTION_PRIMARY, + OPTION_DEFAULT_MODES, +} OutputOpts; + +static OptionInfoRec xf86OutputOptions[] = { + {OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE }, + {OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE }, + {OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE }, + {OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE }, + {OPTION_ABOVE, "Above", OPTV_STRING, {0}, FALSE }, + {OPTION_LEFT_OF, "LeftOf", OPTV_STRING, {0}, FALSE }, + {OPTION_ENABLE, "Enable", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_DISABLE, "Disable", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_MIN_CLOCK, "MinClock", OPTV_FREQ, {0}, FALSE }, + {OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE }, + {OPTION_IGNORE, "Ignore", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE }, + {OPTION_PANNING, "Panning", OPTV_STRING, {0}, FALSE }, + {OPTION_PRIMARY, "Primary", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_DEFAULT_MODES, "DefaultModes", OPTV_BOOLEAN, {0}, FALSE }, + {-1, NULL, OPTV_NONE, {0}, FALSE }, +}; + +enum { + OPTION_MODEDEBUG, +}; + +static OptionInfoRec xf86DeviceOptions[] = { + {OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE }, + {-1, NULL, OPTV_NONE, {0}, FALSE }, +}; + +static void +xf86OutputSetMonitor (xf86OutputPtr output) +{ + char *option_name; + char *monitor; + + if (!output->name) + return; + + free(output->options); + + output->options = xnfalloc (sizeof (xf86OutputOptions)); + memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions)); + + XNFasprintf(&option_name, "monitor-%s", output->name); + monitor = xf86findOptionValue (output->scrn->options, option_name); + if (!monitor) + monitor = output->name; + else + xf86MarkOptionUsedByName (output->scrn->options, option_name); + free(option_name); + output->conf_monitor = xf86findMonitor (monitor, + xf86configptr->conf_monitor_lst); + /* + * Find the monitor section of the screen and use that + */ + if (!output->conf_monitor && output->use_screen_monitor) + output->conf_monitor = xf86findMonitor (output->scrn->monitor->id, + xf86configptr->conf_monitor_lst); + if (output->conf_monitor) + { + xf86DrvMsg (output->scrn->scrnIndex, X_INFO, + "Output %s using monitor section %s\n", + output->name, output->conf_monitor->mon_identifier); + xf86ProcessOptions (output->scrn->scrnIndex, + output->conf_monitor->mon_option_lst, + output->options); + } + else + xf86DrvMsg (output->scrn->scrnIndex, X_INFO, + "Output %s has no monitor section\n", + output->name); +} + +static Bool +xf86OutputEnabled (xf86OutputPtr output, Bool strict) +{ + Bool enable, disable; + + /* check to see if this output was enabled in the config file */ + if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable) + { + xf86DrvMsg (output->scrn->scrnIndex, X_INFO, + "Output %s enabled by config file\n", output->name); + return TRUE; + } + /* or if this output was disabled in the config file */ + if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable) + { + xf86DrvMsg (output->scrn->scrnIndex, X_INFO, + "Output %s disabled by config file\n", output->name); + return FALSE; + } + + /* If not, try to only light up the ones we know are connected */ + if (strict) { + enable = output->status == XF86OutputStatusConnected; + } + /* But if that fails, try to light up even outputs we're unsure of */ + else { + enable = output->status != XF86OutputStatusDisconnected; + } + + xf86DrvMsg (output->scrn->scrnIndex, X_INFO, + "Output %s %sconnected\n", output->name, enable ? "" : "dis"); + return enable; +} + +static Bool +xf86OutputIgnored (xf86OutputPtr output) +{ + return xf86ReturnOptValBool (output->options, OPTION_IGNORE, FALSE); +} + +static char *direction[4] = { + "normal", + "left", + "inverted", + "right" +}; + +static Rotation +xf86OutputInitialRotation (xf86OutputPtr output) +{ + char *rotate_name = xf86GetOptValString (output->options, + OPTION_ROTATE); + int i; + + if (!rotate_name) { + if (output->initial_rotation) + return output->initial_rotation; + return RR_Rotate_0; + } + + for (i = 0; i < 4; i++) + if (xf86nameCompare (direction[i], rotate_name) == 0) + return 1 << i; + return RR_Rotate_0; +} + +xf86OutputPtr +xf86OutputCreate (ScrnInfoPtr scrn, + const xf86OutputFuncsRec *funcs, + const char *name) +{ + xf86OutputPtr output, *outputs; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int len; + Bool primary; + + if (name) + len = strlen (name) + 1; + else + len = 0; + + output = calloc(sizeof (xf86OutputRec) + len, 1); + if (!output) + return NULL; + output->scrn = scrn; + output->funcs = funcs; + if (name) + { + output->name = (char *) (output + 1); + strcpy (output->name, name); + } + output->subpixel_order = SubPixelUnknown; + /* + * Use the old per-screen monitor section for the first output + */ + output->use_screen_monitor = (xf86_config->num_output == 0); +#ifdef RANDR_12_INTERFACE + output->randr_output = NULL; +#endif + if (name) + { + xf86OutputSetMonitor (output); + if (xf86OutputIgnored (output)) + { + free(output); + return FALSE; + } + } + + + if (xf86_config->output) + outputs = realloc(xf86_config->output, + (xf86_config->num_output + 1) * sizeof (xf86OutputPtr)); + else + outputs = malloc((xf86_config->num_output + 1) * sizeof (xf86OutputPtr)); + if (!outputs) + { + free(output); + return NULL; + } + + xf86_config->output = outputs; + + if (xf86GetOptValBool (output->options, OPTION_PRIMARY, &primary) && primary) + { + memmove(xf86_config->output + 1, xf86_config->output, + xf86_config->num_output * sizeof (xf86OutputPtr)); + xf86_config->output[0] = output; + } + else + { + xf86_config->output[xf86_config->num_output] = output; + } + + xf86_config->num_output++; + + return output; +} + +Bool +xf86OutputRename (xf86OutputPtr output, const char *name) +{ + char *newname = strdup(name); + + if (!newname) + return FALSE; /* so sorry... */ + + if (output->name && output->name != (char *) (output + 1)) + free(output->name); + output->name = newname; + xf86OutputSetMonitor (output); + if (xf86OutputIgnored (output)) + return FALSE; + return TRUE; +} + +void +xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor) +{ + if (use_screen_monitor != output->use_screen_monitor) + { + output->use_screen_monitor = use_screen_monitor; + xf86OutputSetMonitor (output); + } +} + +void +xf86OutputDestroy (xf86OutputPtr output) +{ + ScrnInfoPtr scrn = output->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + (*output->funcs->destroy) (output); + while (output->probed_modes) + xf86DeleteMode (&output->probed_modes, output->probed_modes); + for (o = 0; o < xf86_config->num_output; o++) + if (xf86_config->output[o] == output) + { + memmove (&xf86_config->output[o], + &xf86_config->output[o+1], + ((xf86_config->num_output - (o + 1)) * sizeof(void*))); + xf86_config->num_output--; + break; + } + if (output->name && output->name != (char *) (output + 1)) + free(output->name); + free(output); +} + +/* + * Called during CreateScreenResources to hook up RandR + */ +static Bool +xf86CrtcCreateScreenResources (ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + + screen->CreateScreenResources = config->CreateScreenResources; + + if (!(*screen->CreateScreenResources)(screen)) + return FALSE; + + if (!xf86RandR12CreateScreenResources (screen)) + return FALSE; + + return TRUE; +} + +/* + * Clean up config on server reset + */ +static Bool +xf86CrtcCloseScreen (int index, ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o, c; + + screen->CloseScreen = config->CloseScreen; + + xf86RotateCloseScreen (screen); + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->randr_output = NULL; + } + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + + crtc->randr_crtc = NULL; + } + xf86RandR12CloseScreen (screen); + + return screen->CloseScreen (index, screen); +} + +/* + * Called at ScreenInit time to set up + */ +#ifdef RANDR_13_INTERFACE +int +#else +Bool +#endif +xf86CrtcScreenInit (ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + /* Rotation */ + xf86DrvMsg(scrn->scrnIndex, X_INFO, "RandR 1.2 enabled, ignore the following RandR disabled message.\n"); + xf86DisableRandR(); /* Disable old RandR extension support */ + xf86RandR12Init (screen); + + /* support all rotations if every crtc has the shadow alloc funcs */ + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + if (!crtc->funcs->shadow_allocate || !crtc->funcs->shadow_create) + break; + } + if (c == config->num_crtc) + { + xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 | + RR_Rotate_180 | RR_Rotate_270 | + RR_Reflect_X | RR_Reflect_Y); + xf86RandR12SetTransformSupport (screen, TRUE); + } + else + { + xf86RandR12SetRotations (screen, RR_Rotate_0); + xf86RandR12SetTransformSupport (screen, FALSE); + } + + /* Wrap CreateScreenResources so we can initialize the RandR code */ + config->CreateScreenResources = screen->CreateScreenResources; + screen->CreateScreenResources = xf86CrtcCreateScreenResources; + + config->CloseScreen = screen->CloseScreen; + screen->CloseScreen = xf86CrtcCloseScreen; + +#ifdef XFreeXDGA + _xf86_di_dga_init_internal(screen); +#endif +#ifdef RANDR_13_INTERFACE + return RANDR_INTERFACE_VERSION; +#else + return TRUE; +#endif +} + +static DisplayModePtr +xf86DefaultMode (xf86OutputPtr output, int width, int height) +{ + DisplayModePtr target_mode = NULL; + DisplayModePtr mode; + int target_diff = 0; + int target_preferred = 0; + int mm_height; + + mm_height = output->mm_height; + if (!mm_height) + mm_height = (768 * 25.4) / DEFAULT_DPI; + /* + * Pick a mode closest to DEFAULT_DPI + */ + for (mode = output->probed_modes; mode; mode = mode->next) + { + int dpi; + int preferred = (((mode->type & M_T_PREFERRED) != 0) + + ((mode->type & M_T_USERPREF) != 0)); + int diff; + + if (xf86ModeWidth (mode, output->initial_rotation) > width || + xf86ModeHeight (mode, output->initial_rotation) > height) + continue; + + /* yes, use VDisplay here, not xf86ModeHeight */ + dpi = (mode->VDisplay * 254) / (mm_height * 10); + diff = dpi - DEFAULT_DPI; + diff = diff < 0 ? -diff : diff; + if (target_mode == NULL || (preferred > target_preferred) || + (preferred == target_preferred && diff < target_diff)) + { + target_mode = mode; + target_diff = diff; + target_preferred = preferred; + } + } + return target_mode; +} + +static DisplayModePtr +xf86ClosestMode (xf86OutputPtr output, + DisplayModePtr match, Rotation match_rotation, + int width, int height) +{ + DisplayModePtr target_mode = NULL; + DisplayModePtr mode; + int target_diff = 0; + + /* + * Pick a mode closest to the specified mode + */ + for (mode = output->probed_modes; mode; mode = mode->next) + { + int dx, dy; + int diff; + + if (xf86ModeWidth (mode, output->initial_rotation) > width || + xf86ModeHeight (mode, output->initial_rotation) > height) + continue; + + /* exact matches are preferred */ + if (output->initial_rotation == match_rotation && + xf86ModesEqual (mode, match)) + return mode; + + dx = xf86ModeWidth (match, match_rotation) - xf86ModeWidth (mode, output->initial_rotation); + dy = xf86ModeHeight (match, match_rotation) - xf86ModeHeight (mode, output->initial_rotation); + diff = dx * dx + dy * dy; + if (target_mode == NULL || diff < target_diff) + { + target_mode = mode; + target_diff = diff; + } + } + return target_mode; +} + +static DisplayModePtr +xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height) +{ + DisplayModePtr mode; + + for (mode = output->probed_modes; mode; mode = mode->next) + { + if (xf86ModeWidth (mode, output->initial_rotation) > width || + xf86ModeHeight (mode, output->initial_rotation) > height) + continue; + + if (mode->type & M_T_PREFERRED) + return mode; + } + return NULL; +} + +static DisplayModePtr +xf86OutputHasUserPreferredMode (xf86OutputPtr output) +{ + DisplayModePtr mode, first = output->probed_modes; + + for (mode = first; mode && mode->next != first; mode = mode->next) + if (mode->type & M_T_USERPREF) + return mode; + + return NULL; +} + +static int +xf86PickCrtcs (ScrnInfoPtr scrn, + xf86CrtcPtr *best_crtcs, + DisplayModePtr *modes, + int n, + int width, + int height) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int c, o; + xf86OutputPtr output; + xf86CrtcPtr crtc; + xf86CrtcPtr *crtcs; + xf86CrtcPtr best_crtc; + int best_score; + int score; + int my_score; + + if (n == config->num_output) + return 0; + output = config->output[n]; + + /* + * Compute score with this output disabled + */ + best_crtcs[n] = NULL; + best_crtc = NULL; + best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height); + if (modes[n] == NULL) + return best_score; + + crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr)); + if (!crtcs) + return best_score; + + my_score = 1; + /* Score outputs that are known to be connected higher */ + if (output->status == XF86OutputStatusConnected) + my_score++; + /* Score outputs with preferred modes higher */ + if (xf86OutputHasPreferredMode (output, width, height)) + my_score++; + /* + * Select a crtc for this output and + * then attempt to configure the remaining + * outputs + */ + for (c = 0; c < config->num_crtc; c++) + { + if ((output->possible_crtcs & (1 << c)) == 0) + continue; + + crtc = config->crtc[c]; + /* + * Check to see if some other output is + * using this crtc + */ + for (o = 0; o < n; o++) + if (best_crtcs[o] == crtc) + break; + if (o < n) + { + /* + * If the two outputs desire the same mode, + * see if they can be cloned + */ + if (xf86ModesEqual (modes[o], modes[n]) && + config->output[o]->initial_rotation == config->output[n]->initial_rotation && + config->output[o]->initial_x == config->output[n]->initial_x && + config->output[o]->initial_y == config->output[n]->initial_y) + { + if ((output->possible_clones & (1 << o)) == 0) + continue; /* nope, try next CRTC */ + } + else + continue; /* different modes, can't clone */ + } + crtcs[n] = crtc; + memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr)); + score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height); + if (score > best_score) + { + best_crtc = crtc; + best_score = score; + memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr)); + } + } + free(crtcs); + return best_score; +} + + +/* + * Compute the virtual size necessary to place all of the available + * crtcs in the specified configuration. + * + * canGrow indicates that the driver can make the screen larger than its initial + * configuration. If FALSE, this function will enlarge the screen to include + * the largest available mode. + */ + +static void +xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp, + Bool canGrow) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int width = 0, height = 0; + int o; + int c; + int s; + + for (c = 0; c < config->num_crtc; c++) + { + int crtc_width = 0, crtc_height = 0; + xf86CrtcPtr crtc = config->crtc[c]; + + if (crtc->enabled) + { + crtc_width = crtc->desiredX + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation); + crtc_height = crtc->desiredY + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation); + } + if (!canGrow) { + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + for (s = 0; s < config->num_crtc; s++) + if (output->possible_crtcs & (1 << s)) + { + DisplayModePtr mode; + for (mode = output->probed_modes; mode; mode = mode->next) + { + if (mode->HDisplay > crtc_width) + crtc_width = mode->HDisplay; + if (mode->VDisplay > crtc_width) + crtc_width = mode->VDisplay; + if (mode->VDisplay > crtc_height) + crtc_height = mode->VDisplay; + if (mode->HDisplay > crtc_height) + crtc_height = mode->HDisplay; + } + } + } + } + if (crtc_width > width) + width = crtc_width; + if (crtc_height > height) + height = crtc_height; + } + if (config->maxWidth && width > config->maxWidth) width = config->maxWidth; + if (config->maxHeight && height > config->maxHeight) height = config->maxHeight; + if (config->minWidth && width < config->minWidth) width = config->minWidth; + if (config->minHeight && height < config->minHeight) height = config->minHeight; + *widthp = width; + *heightp = height; +} + +#define POSITION_UNSET -100000 + +/* + * check if the user configured any outputs at all + * with either a position or a relative setting or a mode. + */ +static Bool +xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + Bool user_conf = FALSE; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + char *position; + char *relative_name; + OutputOpts relation; + int r; + static const OutputOpts relations[] = { + OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF + }; + + position = xf86GetOptValString (output->options, + OPTION_POSITION); + if (position) + user_conf = TRUE; + + relation = 0; + relative_name = NULL; + for (r = 0; r < 4; r++) + { + relation = relations[r]; + relative_name = xf86GetOptValString (output->options, + relation); + if (relative_name) + break; + } + if (relative_name) + user_conf = TRUE; + + modes[o] = xf86OutputHasUserPreferredMode(output); + if (modes[o]) + user_conf = TRUE; + } + + return user_conf; +} + +static Bool +xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + int min_x, min_y; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->initial_x = output->initial_y = POSITION_UNSET; + } + + /* + * Loop until all outputs are set + */ + for (;;) + { + Bool any_set = FALSE; + Bool keep_going = FALSE; + + for (o = 0; o < config->num_output; o++) + { + static const OutputOpts relations[] = { + OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF + }; + xf86OutputPtr output = config->output[o]; + xf86OutputPtr relative; + char *relative_name; + char *position; + OutputOpts relation; + int r; + + if (output->initial_x != POSITION_UNSET) + continue; + position = xf86GetOptValString (output->options, + OPTION_POSITION); + /* + * Absolute position wins + */ + if (position) + { + int x, y; + if (sscanf (position, "%d %d", &x, &y) == 2) + { + output->initial_x = x; + output->initial_y = y; + } + else + { + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Output %s position not of form \"x y\"\n", + output->name); + output->initial_x = output->initial_y = 0; + } + any_set = TRUE; + continue; + } + /* + * Next comes relative positions + */ + relation = 0; + relative_name = NULL; + for (r = 0; r < 4; r++) + { + relation = relations[r]; + relative_name = xf86GetOptValString (output->options, + relation); + if (relative_name) + break; + } + if (relative_name) + { + int or; + relative = NULL; + for (or = 0; or < config->num_output; or++) + { + xf86OutputPtr out_rel = config->output[or]; + XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor; + + if (rel_mon) + { + if (xf86nameCompare (rel_mon->mon_identifier, + relative_name) == 0) + { + relative = config->output[or]; + break; + } + } + if (strcmp (out_rel->name, relative_name) == 0) + { + relative = config->output[or]; + break; + } + } + if (!relative) + { + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Cannot position output %s relative to unknown output %s\n", + output->name, relative_name); + output->initial_x = 0; + output->initial_y = 0; + any_set = TRUE; + continue; + } + if (!modes[or]) + { + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Cannot position output %s relative to output %s without modes\n", + output->name, relative_name); + output->initial_x = 0; + output->initial_y = 0; + any_set = TRUE; + continue; + } + if (relative->initial_x == POSITION_UNSET) + { + keep_going = TRUE; + continue; + } + output->initial_x = relative->initial_x; + output->initial_y = relative->initial_y; + switch (relation) { + case OPTION_BELOW: + output->initial_y += xf86ModeHeight (modes[or], relative->initial_rotation); + break; + case OPTION_RIGHT_OF: + output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation); + break; + case OPTION_ABOVE: + if (modes[o]) + output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation); + break; + case OPTION_LEFT_OF: + if (modes[o]) + output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation); + break; + default: + break; + } + any_set = TRUE; + continue; + } + + /* Nothing set, just stick them at 0,0 */ + output->initial_x = 0; + output->initial_y = 0; + any_set = TRUE; + } + if (!keep_going) + break; + if (!any_set) + { + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + if (output->initial_x == POSITION_UNSET) + { + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Output position loop. Moving %s to 0,0\n", + output->name); + output->initial_x = output->initial_y = 0; + break; + } + } + } + } + + /* + * normalize positions + */ + min_x = 1000000; + min_y = 1000000; + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + if (output->initial_x < min_x) + min_x = output->initial_x; + if (output->initial_y < min_y) + min_y = output->initial_y; + } + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->initial_x -= min_x; + output->initial_y -= min_y; + } + return TRUE; +} + +static void +xf86InitialPanning (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + char *panning = xf86GetOptValString (output->options, OPTION_PANNING); + int width, height, left, top; + int track_width, track_height, track_left, track_top; + int brdr[4]; + + memset (&output->initialTotalArea, 0, sizeof(BoxRec)); + memset (&output->initialTrackingArea, 0, sizeof(BoxRec)); + memset (output->initialBorder, 0, 4*sizeof(INT16)); + + if (! panning) + continue; + + switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d", + &width, &height, &left, &top, + &track_width, &track_height, &track_left, &track_top, + &brdr[0], &brdr[1], &brdr[2], &brdr[3])) { + case 12: + output->initialBorder[0] = brdr[0]; + output->initialBorder[1] = brdr[1]; + output->initialBorder[2] = brdr[2]; + output->initialBorder[3] = brdr[3]; + /* fall through */ + case 8: + output->initialTrackingArea.x1 = track_left; + output->initialTrackingArea.y1 = track_top; + output->initialTrackingArea.x2 = track_left + track_width; + output->initialTrackingArea.y2 = track_top + track_height; + /* fall through */ + case 4: + output->initialTotalArea.x1 = left; + output->initialTotalArea.y1 = top; + /* fall through */ + case 2: + output->initialTotalArea.x2 = output->initialTotalArea.x1 + width; + output->initialTotalArea.y2 = output->initialTotalArea.y1 + height; + break; + default: + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Broken panning specification '%s' for output %s in config file\n", + panning, output->name); + } + } +} + +/** Return - 0 + if a should be earlier, same or later than b in list + */ +static int +xf86ModeCompare (DisplayModePtr a, DisplayModePtr b) +{ + int diff; + + diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0); + if (diff) + return diff; + diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay; + if (diff) + return diff; + diff = b->Clock - a->Clock; + return diff; +} + +/** + * Insertion sort input in-place and return the resulting head + */ +static DisplayModePtr +xf86SortModes (DisplayModePtr input) +{ + DisplayModePtr output = NULL, i, o, n, *op, prev; + + /* sort by preferred status and pixel area */ + while (input) + { + i = input; + input = input->next; + for (op = &output; (o = *op); op = &o->next) + if (xf86ModeCompare (o, i) > 0) + break; + i->next = *op; + *op = i; + } + /* prune identical modes */ + for (o = output; o && (n = o->next); o = n) + { + if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n)) + { + o->next = n->next; + free(n->name); + free(n); + n = o; + } + } + /* hook up backward links */ + prev = NULL; + for (o = output; o; o = o->next) + { + o->prev = prev; + prev = o; + } + return output; +} + +static char * +preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output) +{ + char *preferred_mode = NULL; + + /* Check for a configured preference for a particular mode */ + preferred_mode = xf86GetOptValString (output->options, + OPTION_PREFERRED_MODE); + if (preferred_mode) + return preferred_mode; + + if (pScrn->display->modes && *pScrn->display->modes) + preferred_mode = *pScrn->display->modes; + + return preferred_mode; +} + +static void +GuessRangeFromModes(MonPtr mon, DisplayModePtr mode) +{ + if (!mon || !mode) + return; + + mon->nHsync = 1; + mon->hsync[0].lo = 1024.0; + mon->hsync[0].hi = 0.0; + + mon->nVrefresh = 1; + mon->vrefresh[0].lo = 1024.0; + mon->vrefresh[0].hi = 0.0; + + while (mode) { + if (!mode->HSync) + mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal); + + if (!mode->VRefresh) + mode->VRefresh = (1000.0 * ((float) mode->Clock)) / + ((float) (mode->HTotal * mode->VTotal)); + + if (mode->HSync < mon->hsync[0].lo) + mon->hsync[0].lo = mode->HSync; + + if (mode->HSync > mon->hsync[0].hi) + mon->hsync[0].hi = mode->HSync; + + if (mode->VRefresh < mon->vrefresh[0].lo) + mon->vrefresh[0].lo = mode->VRefresh; + + if (mode->VRefresh > mon->vrefresh[0].hi) + mon->vrefresh[0].hi = mode->VRefresh; + + mode = mode->next; + } + + /* stretch out the bottom to fit 640x480@60 */ + if (mon->hsync[0].lo > 31.0) + mon->hsync[0].lo = 31.0; + if (mon->vrefresh[0].lo > 58.0) + mon->vrefresh[0].lo = 58.0; +} + +enum det_monrec_source { + sync_config, sync_edid, sync_default +}; + +struct det_monrec_parameter { + MonRec *mon_rec; + int *max_clock; + Bool set_hsync; + Bool set_vrefresh; + enum det_monrec_source *sync_source; +}; + +static void handle_detailed_monrec(struct detailed_monitor_section *det_mon, + void *data) +{ + struct det_monrec_parameter *p; + p = (struct det_monrec_parameter *)data; + + if (det_mon->type == DS_RANGES) { + struct monitor_ranges *ranges = &det_mon->section.ranges; + if (p->set_hsync && ranges->max_h) { + p->mon_rec->hsync[p->mon_rec->nHsync].lo = ranges->min_h; + p->mon_rec->hsync[p->mon_rec->nHsync].hi = ranges->max_h; + p->mon_rec->nHsync++; + if (*p->sync_source == sync_default) + *p->sync_source = sync_edid; + } + if (p->set_vrefresh && ranges->max_v) { + p->mon_rec->vrefresh[p->mon_rec->nVrefresh].lo = ranges->min_v; + p->mon_rec->vrefresh[p->mon_rec->nVrefresh].hi = ranges->max_v; + p->mon_rec->nVrefresh++; + if (*p->sync_source == sync_default) + *p->sync_source = sync_edid; + } + if (ranges->max_clock * 1000 > *p->max_clock) + *p->max_clock = ranges->max_clock * 1000; + } +} + +void +xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + /* When canGrow was TRUE in the initial configuration we have to + * compare against the maximum values so that we don't drop modes. + * When canGrow was FALSE, the maximum values would have been clamped + * anyway. + */ + if (maxX == 0 || maxY == 0) { + maxX = config->maxWidth; + maxY = config->maxHeight; + } + + /* Probe the list of modes for each output. */ + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + DisplayModePtr mode; + DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL; + char *preferred_mode; + xf86MonPtr edid_monitor; + XF86ConfMonitorPtr conf_monitor; + MonRec mon_rec; + int min_clock = 0; + int max_clock = 0; + double clock; + Bool add_default_modes; + Bool debug_modes = config->debug_modes || + xf86Initialising; + enum det_monrec_source sync_source = sync_default; + + while (output->probed_modes != NULL) + xf86DeleteMode(&output->probed_modes, output->probed_modes); + + /* + * Check connection status + */ + output->status = (*output->funcs->detect)(output); + + if (output->status == XF86OutputStatusDisconnected && + !xf86ReturnOptValBool(output->options, OPTION_ENABLE, FALSE)) + { + xf86OutputSetEDID (output, NULL); + continue; + } + + memset (&mon_rec, '\0', sizeof (mon_rec)); + + conf_monitor = output->conf_monitor; + + if (conf_monitor) + { + int i; + + for (i = 0; i < conf_monitor->mon_n_hsync; i++) + { + mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo; + mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi; + mon_rec.nHsync++; + sync_source = sync_config; + } + for (i = 0; i < conf_monitor->mon_n_vrefresh; i++) + { + mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo; + mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi; + mon_rec.nVrefresh++; + sync_source = sync_config; + } + config_modes = xf86GetMonitorModes (scrn, conf_monitor); + } + + output_modes = (*output->funcs->get_modes) (output); + + /* + * If the user has a preference, respect it. + * Otherwise, don't second-guess the driver. + */ + if (!xf86GetOptValBool(output->options, OPTION_DEFAULT_MODES, + &add_default_modes)) + add_default_modes = (output_modes == NULL); + + edid_monitor = output->MonInfo; + + if (edid_monitor) + { + struct det_monrec_parameter p; + struct disp_features *features = &edid_monitor->features; + + /* if display is not continuous-frequency, don't add default modes */ + if (!GTF_SUPPORTED(features->msc)) + add_default_modes = FALSE; + + p.mon_rec = &mon_rec; + p.max_clock = &max_clock; + p.set_hsync = mon_rec.nHsync == 0; + p.set_vrefresh = mon_rec.nVrefresh == 0; + p.sync_source = &sync_source; + + xf86ForEachDetailedBlock(edid_monitor, + handle_detailed_monrec, + &p); + } + + if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK, + OPTUNITS_KHZ, &clock)) + min_clock = (int) clock; + if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK, + OPTUNITS_KHZ, &clock)) + max_clock = (int) clock; + + /* If we still don't have a sync range, guess wildly */ + if (!mon_rec.nHsync || !mon_rec.nVrefresh) + GuessRangeFromModes(&mon_rec, output_modes); + + /* + * These limits will end up setting a 1024x768@60Hz mode by default, + * which seems like a fairly good mode to use when nothing else is + * specified + */ + if (mon_rec.nHsync == 0) + { + mon_rec.hsync[0].lo = 31.0; + mon_rec.hsync[0].hi = 55.0; + mon_rec.nHsync = 1; + } + if (mon_rec.nVrefresh == 0) + { + mon_rec.vrefresh[0].lo = 58.0; + mon_rec.vrefresh[0].hi = 62.0; + mon_rec.nVrefresh = 1; + } + + if (add_default_modes) + default_modes = xf86GetDefaultModes (); + + /* + * If this is not an RB monitor, remove RB modes from the default + * pool. RB modes from the config or the monitor itself are fine. + */ + if (!mon_rec.reducedblanking) + xf86ValidateModesReducedBlanking (scrn, default_modes); + + if (sync_source == sync_config) + { + /* + * Check output and config modes against sync range from config file + */ + xf86ValidateModesSync (scrn, output_modes, &mon_rec); + xf86ValidateModesSync (scrn, config_modes, &mon_rec); + } + /* + * Check default modes against sync range + */ + xf86ValidateModesSync (scrn, default_modes, &mon_rec); + /* + * Check default modes against monitor max clock + */ + if (max_clock) { + xf86ValidateModesClocks(scrn, default_modes, + &min_clock, &max_clock, 1); + xf86ValidateModesClocks(scrn, output_modes, + &min_clock, &max_clock, 1); + } + + output->probed_modes = NULL; + output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes); + output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes); + output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes); + + /* + * Check all modes against max size, interlace, and doublescan + */ + if (maxX && maxY) + xf86ValidateModesSize (scrn, output->probed_modes, + maxX, maxY, 0); + + { + int flags = (output->interlaceAllowed ? V_INTERLACE : 0) | + (output->doubleScanAllowed ? V_DBLSCAN : 0); + xf86ValidateModesFlags (scrn, output->probed_modes, flags); + } + + /* + * Check all modes against output + */ + for (mode = output->probed_modes; mode != NULL; mode = mode->next) + if (mode->status == MODE_OK) + mode->status = (*output->funcs->mode_valid)(output, mode); + + xf86PruneInvalidModes(scrn, &output->probed_modes, debug_modes); + + output->probed_modes = xf86SortModes (output->probed_modes); + + /* Check for a configured preference for a particular mode */ + preferred_mode = preferredMode(scrn, output); + + if (preferred_mode) + { + for (mode = output->probed_modes; mode; mode = mode->next) + { + if (!strcmp (preferred_mode, mode->name)) + { + if (mode != output->probed_modes) + { + if (mode->prev) + mode->prev->next = mode->next; + if (mode->next) + mode->next->prev = mode->prev; + mode->next = output->probed_modes; + output->probed_modes->prev = mode; + mode->prev = NULL; + output->probed_modes = mode; + } + mode->type |= (M_T_PREFERRED|M_T_USERPREF); + break; + } + } + } + + output->initial_rotation = xf86OutputInitialRotation (output); + + if (debug_modes) { + if (output->probed_modes != NULL) { + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "Printing probed modes for output %s\n", + output->name); + } else { + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "No remaining probed modes for output %s\n", + output->name); + } + } + for (mode = output->probed_modes; mode != NULL; mode = mode->next) + { + /* The code to choose the best mode per pipe later on will require + * VRefresh to be set. + */ + mode->VRefresh = xf86ModeVRefresh(mode); + xf86SetModeCrtc(mode, INTERLACE_HALVE_V); + + if (debug_modes) + xf86PrintModeline(scrn->scrnIndex, mode); + } + } +} + + +/** + * Copy one of the output mode lists to the ScrnInfo record + */ + +/* XXX where does this function belong? Here? */ +void +xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y); + +static DisplayModePtr +biggestMode(DisplayModePtr a, DisplayModePtr b) +{ + int A, B; + + if (!a) + return b; + if (!b) + return a; + + A = a->HDisplay * a->VDisplay; + B = b->HDisplay * b->VDisplay; + + if (A > B) + return a; + + return b; +} + +static xf86OutputPtr +SetCompatOutput(xf86CrtcConfigPtr config) +{ + xf86OutputPtr output = NULL, test = NULL; + DisplayModePtr maxmode = NULL, testmode, mode; + int o, compat = -1, count, mincount = 0; + + /* Look for one that's definitely connected */ + for (o = 0; o < config->num_output; o++) + { + test = config->output[o]; + if (!test->crtc) + continue; + if (test->status != XF86OutputStatusConnected) + continue; + if (!test->probed_modes) + continue; + + testmode = mode = test->probed_modes; + for (count = 0; mode; mode = mode->next, count++) + testmode = biggestMode(testmode, mode); + + if (!output) { + output = test; + compat = o; + maxmode = testmode; + mincount = count; + } else if (maxmode == biggestMode(maxmode, testmode)) { + output = test; + compat = o; + maxmode = testmode; + mincount = count; + } else if ((maxmode->HDisplay == testmode->HDisplay) && + (maxmode->VDisplay == testmode->VDisplay) && + count <= mincount) { + output = test; + compat = o; + maxmode = testmode; + mincount = count; + } + } + + /* If we didn't find one, take anything we can get */ + if (!output) + { + for (o = 0; o < config->num_output; o++) + { + test = config->output[o]; + if (!test->crtc) + continue; + if (!test->probed_modes) + continue; + + if (!output) { + output = test; + compat = o; + } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) { + output = test; + compat = o; + } + } + } + + if (compat >= 0) { + config->compat_output = compat; + } else { + /* Don't change the compat output when no valid outputs found */ + output = config->output[config->compat_output]; + } + + return output; +} + +void +xf86SetScrnInfoModes (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + xf86OutputPtr output; + xf86CrtcPtr crtc; + DisplayModePtr last, mode = NULL; + + output = SetCompatOutput(config); + + if (!output) + return; /* punt */ + + crtc = output->crtc; + + /* Clear any existing modes from scrn->modes */ + while (scrn->modes != NULL) + xf86DeleteMode(&scrn->modes, scrn->modes); + + /* Set scrn->modes to the mode list for the 'compat' output */ + scrn->modes = xf86DuplicateModes(scrn, output->probed_modes); + + if (crtc) { + for (mode = scrn->modes; mode; mode = mode->next) + if (xf86ModesEqual (mode, &crtc->desiredMode)) + break; + } + + if (scrn->modes != NULL) { + /* For some reason, scrn->modes is circular, unlike the other mode + * lists. How great is that? + */ + for (last = scrn->modes; last && last->next; last = last->next) + ; + last->next = scrn->modes; + scrn->modes->prev = last; + if (mode) { + while (scrn->modes != mode) + scrn->modes = scrn->modes->next; + } + } + scrn->currentMode = scrn->modes; +#ifdef XFreeXDGA + if (scrn->pScreen) + _xf86_di_dga_reinit_internal(scrn->pScreen); +#endif +} + +static Bool +xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + Bool *enabled) +{ + Bool any_enabled = FALSE; + int o; + + for (o = 0; o < config->num_output; o++) + any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE); + + if (!any_enabled) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "No outputs definitely connected, trying again...\n"); + + for (o = 0; o < config->num_output; o++) + any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], FALSE); + } + + return any_enabled; +} + +static Bool +nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index) +{ + int o = *index; + + for (o++; o < config->num_output; o++) { + if (enabled[o]) { + *index = o; + return TRUE; + } + } + + return FALSE; +} + +static Bool +aspectMatch(float a, float b) +{ + return fabs(1 - (a / b)) < 0.05; +} + +static DisplayModePtr +nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect) +{ + DisplayModePtr m = NULL; + + if (!o) + return NULL; + + if (!last) + m = o->probed_modes; + else + m = last->next; + + for (; m; m = m->next) + if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay)) + return m; + + return NULL; +} + +static DisplayModePtr +bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) +{ + int o = -1, p; + DisplayModePtr mode = NULL, test = NULL, match = NULL; + + if (!nextEnabledOutput(config, enabled, &o)) + return NULL; + while ((mode = nextAspectMode(config->output[o], mode, aspect))) { + test = mode; + for (p = o; nextEnabledOutput(config, enabled, &p); ) { + test = xf86OutputFindClosestMode(config->output[p], mode); + if (!test) + break; + if (test->HDisplay != mode->HDisplay || + test->VDisplay != mode->VDisplay) { + test = NULL; + break; + } + } + + /* if we didn't match it on all outputs, try the next one */ + if (!test) + continue; + + /* if it's bigger than the last one, save it */ + if (!match || (test->HDisplay > match->HDisplay)) + match = test; + } + + /* return the biggest one found */ + return match; +} + +static Bool +xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o, p; + int max_pref_width = 0, max_pref_height = 0; + DisplayModePtr *preferred, *preferred_match; + Bool ret = FALSE; + + preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr)); + preferred_match = xnfcalloc(config->num_output, sizeof(DisplayModePtr)); + + /* Check if the preferred mode is available on all outputs */ + for (p = -1; nextEnabledOutput(config, enabled, &p); ) { + Rotation r = config->output[p]->initial_rotation; + DisplayModePtr mode; + if ((preferred[p] = xf86OutputHasPreferredMode(config->output[p], + width, height))) { + int pref_width = xf86ModeWidth(preferred[p], r); + int pref_height = xf86ModeHeight(preferred[p], r); + Bool all_match = TRUE; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + Bool match = FALSE; + xf86OutputPtr output = config->output[o]; + if (o == p) + continue; + + for (mode = output->probed_modes; mode; mode = mode->next) { + Rotation r = output->initial_rotation; + if (xf86ModeWidth(mode, r) == pref_width && + xf86ModeHeight(mode, r) == pref_height) { + preferred[o] = mode; + match = TRUE; + } + } + + all_match &= match; + } + + if (all_match && + (pref_width*pref_height > max_pref_width*max_pref_height)) { + for (o = -1; nextEnabledOutput(config, enabled, &o); ) + preferred_match[o] = preferred[o]; + max_pref_width = pref_width; + max_pref_height = pref_height; + ret = TRUE; + } + } + } + + /* + * If there's no preferred mode, but only one monitor, pick the + * biggest mode for its aspect ratio, assuming one exists. + */ + if (!ret) do { + int i = 0; + float aspect = 0.0; + + /* count the number of enabled outputs */ + for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ; + + if (i != 1) + break; + + p = -1; + nextEnabledOutput(config, enabled, &p); + if (config->output[p]->mm_height) + aspect = (float)config->output[p]->mm_width / + (float)config->output[p]->mm_height; + + if (aspect) + preferred_match[p] = bestModeForAspect(config, enabled, aspect); + + if (preferred_match[p]) + ret = TRUE; + + } while (0); + + if (ret) { + /* oh good, there is a match. stash the selected modes and return. */ + memcpy(modes, preferred_match, + config->num_output * sizeof(DisplayModePtr)); + } + + free(preferred); + free(preferred_match); + return ret; +} + +static Bool +xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o; + float aspect = 0.0, *aspects; + xf86OutputPtr output; + Bool ret = FALSE; + DisplayModePtr guess = NULL, aspect_guess = NULL, base_guess = NULL; + + aspects = xnfcalloc(config->num_output, sizeof(float)); + + /* collect the aspect ratios */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + output = config->output[o]; + if (output->mm_height) + aspects[o] = (float)output->mm_width / (float)output->mm_height; + else + aspects[o] = 4.0 / 3.0; + } + + /* check that they're all the same */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + output = config->output[o]; + if (!aspect) { + aspect = aspects[o]; + } else if (!aspectMatch(aspect, aspects[o])) { + goto no_aspect_match; + } + } + + /* if they're all 4:3, just skip ahead and save effort */ + if (!aspectMatch(aspect, 4.0/3.0)) + aspect_guess = bestModeForAspect(config, enabled, aspect); + +no_aspect_match: + base_guess = bestModeForAspect(config, enabled, 4.0/3.0); + + guess = biggestMode(base_guess, aspect_guess); + + if (!guess) + goto out; + + /* found a mode that works everywhere, now apply it */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + modes[o] = xf86OutputFindClosestMode(config->output[o], guess); + } + ret = TRUE; + +out: + free(aspects); + return ret; +} + +static Bool +xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + DisplayModePtr target_mode = NULL; + Rotation target_rotation = RR_Rotate_0; + DisplayModePtr default_mode; + int default_preferred, target_preferred = 0, o; + + /* User preferred > preferred > other modes */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + default_mode = xf86DefaultMode (config->output[o], width, height); + if (!default_mode) + continue; + + default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) + + ((default_mode->type & M_T_USERPREF) != 0)); + + if (default_preferred > target_preferred || !target_mode) { + target_mode = default_mode; + target_preferred = default_preferred; + target_rotation = config->output[o]->initial_rotation; + config->compat_output = o; + } + } + + if (target_mode) + modes[config->compat_output] = target_mode; + + /* Fill in other output modes */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + if (!modes[o]) + modes[o] = xf86ClosestMode(config->output[o], target_mode, + target_rotation, width, height); + } + + return target_mode != NULL; +} + +static Bool +xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o; + + if (xf86UserConfiguredOutputs(scrn, modes)) + return xf86TargetFallback(scrn, config, modes, enabled, width, height); + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) + if (xf86OutputHasUserPreferredMode(config->output[o])) + return + xf86TargetFallback(scrn, config, modes, enabled, width, height); + + return FALSE; +} + +static Bool +xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green, + float gamma_blue) +{ + int i, size = 256; + CARD16 *red, *green, *blue; + + red = malloc(3 * size * sizeof(CARD16)); + green = red + size; + blue = green + size; + + /* Only cause warning if user wanted gamma to be set. */ + if (!crtc->funcs->gamma_set && (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) { + free(red); + return FALSE; + } else if (!crtc->funcs->gamma_set) { + free(red); + return TRUE; + } + + /* At this early stage none of the randr-interface stuff is up. + * So take the default gamma size for lack of something better. + */ + for (i = 0; i < size; i++) { + if (gamma_red == 1.0) + red[i] = i << 8; + else + red[i] = (CARD16)(pow((double)i/(double)(size - 1), + 1. / (double)gamma_red) * (double)(size - 1) * 256); + + if (gamma_green == 1.0) + green[i] = i << 8; + else + green[i] = (CARD16)(pow((double)i/(double)(size - 1), + 1. / (double)gamma_green) * (double)(size - 1) * 256); + + if (gamma_blue == 1.0) + blue[i] = i << 8; + else + blue[i] = (CARD16)(pow((double)i/(double)(size - 1), + 1. / (double)gamma_blue) * (double)(size - 1) * 256); + } + + /* Default size is 256, so anything else is failure. */ + if (size != crtc->gamma_size) { + free(red); + return FALSE; + } + + crtc->gamma_size = size; + memcpy (crtc->gamma_red, red, crtc->gamma_size * sizeof (CARD16)); + memcpy (crtc->gamma_green, green, crtc->gamma_size * sizeof (CARD16)); + memcpy (crtc->gamma_blue, blue, crtc->gamma_size * sizeof (CARD16)); + + /* Do not set gamma now, delay until the crtc is activated. */ + + free(red); + + return TRUE; +} + +static Bool +xf86OutputSetInitialGamma(xf86OutputPtr output) +{ + XF86ConfMonitorPtr mon = output->conf_monitor; + float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0; + + if (!mon) + return TRUE; + + if (!output->crtc) + return FALSE; + + /* Get configured values, where they exist. */ + if (mon->mon_gamma_red >= GAMMA_MIN && + mon->mon_gamma_red <= GAMMA_MAX) + gamma_red = mon->mon_gamma_red; + + if (mon->mon_gamma_green >= GAMMA_MIN && + mon->mon_gamma_green <= GAMMA_MAX) + gamma_green = mon->mon_gamma_green; + + if (mon->mon_gamma_blue >= GAMMA_MIN && + mon->mon_gamma_blue <= GAMMA_MAX) + gamma_blue = mon->mon_gamma_blue; + + /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */ + if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) { + xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n", output->name, gamma_red, gamma_green, gamma_blue); + return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green, gamma_blue); + }else + return TRUE; +} + +/** + * Construct default screen configuration + * + * Given auto-detected (and, eventually, configured) values, + * construct a usable configuration for the system + * + * canGrow indicates that the driver can resize the screen to larger than its + * initially configured size via the config->funcs->resize hook. If TRUE, this + * function will set virtualX and virtualY to match the initial configuration + * and leave config->max{Width,Height} alone. If FALSE, it will bloat + * virtual[XY] to include the largest modes and set config->max{Width,Height} + * accordingly. + */ + +Bool +xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o, c; + xf86CrtcPtr *crtcs; + DisplayModePtr *modes; + Bool *enabled; + int width, height; + int i = scrn->scrnIndex; + Bool have_outputs = TRUE; + Bool ret; + + /* Set up the device options */ + config->options = xnfalloc (sizeof (xf86DeviceOptions)); + memcpy (config->options, xf86DeviceOptions, sizeof (xf86DeviceOptions)); + xf86ProcessOptions (scrn->scrnIndex, + scrn->options, + config->options); + config->debug_modes = xf86ReturnOptValBool (config->options, + OPTION_MODEDEBUG, FALSE); + + if (scrn->display->virtualX) + width = scrn->display->virtualX; + else + width = config->maxWidth; + if (scrn->display->virtualY) + height = scrn->display->virtualY; + else + height = config->maxHeight; + + xf86ProbeOutputModes (scrn, width, height); + + crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr)); + modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr)); + enabled = xnfcalloc (config->num_output, sizeof (Bool)); + + ret = xf86CollectEnabledOutputs(scrn, config, enabled); + if (ret == FALSE && canGrow) { + xf86DrvMsg(i, X_WARNING, "Unable to find connected outputs - setting %dx%d initial framebuffer\n", + NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT); + have_outputs = FALSE; + } else { + if (xf86TargetUserpref(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n"); + else if (xf86TargetPreferred(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n"); + else if (xf86TargetAspect(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n"); + else if (xf86TargetFallback(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using sloppy heuristic for initial modes\n"); + else + xf86DrvMsg(i, X_WARNING, "Unable to find initial modes\n"); + } + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + if (!modes[o]) + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Output %s enabled but has no modes\n", + config->output[o]->name); + else + xf86DrvMsg (scrn->scrnIndex, X_INFO, + "Output %s using initial mode %s\n", + config->output[o]->name, modes[o]->name); + } + + /* + * Set the position of each output + */ + if (!xf86InitialOutputPositions (scrn, modes)) + { + free(crtcs); + free(modes); + return FALSE; + } + + /* + * Set initial panning of each output + */ + xf86InitialPanning (scrn); + + /* + * Assign CRTCs to fit output configuration + */ + if (have_outputs && !xf86PickCrtcs (scrn, crtcs, modes, 0, width, height)) + { + free(crtcs); + free(modes); + return FALSE; + } + + /* XXX override xf86 common frame computation code */ + + scrn->display->frameX0 = 0; + scrn->display->frameY0 = 0; + + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + + crtc->enabled = FALSE; + memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode)); + /* Set default gamma for all crtc's. */ + /* This is done to avoid problems later on with cloned outputs. */ + xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0); + } + + if (xf86_crtc_supports_gamma(scrn)) + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n"); + + /* + * Set initial configuration + */ + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + DisplayModePtr mode = modes[o]; + xf86CrtcPtr crtc = crtcs[o]; + + if (mode && crtc) + { + crtc->desiredMode = *mode; + crtc->desiredRotation = output->initial_rotation; + crtc->desiredX = output->initial_x; + crtc->desiredY = output->initial_y; + crtc->desiredTransformPresent = FALSE; + crtc->enabled = TRUE; + memcpy (&crtc->panningTotalArea, &output->initialTotalArea, sizeof(BoxRec)); + memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec)); + memcpy (crtc->panningBorder, output->initialBorder, 4*sizeof(INT16)); + output->crtc = crtc; + if (!xf86OutputSetInitialGamma(output)) + xf86DrvMsg (scrn->scrnIndex, X_WARNING, "Initial gamma correction for output %s: failed.\n", output->name); + } else { + output->crtc = NULL; + } + } + + if (scrn->display->virtualX == 0) + { + /* + * Expand virtual size to cover the current config and potential mode + * switches, if the driver can't enlarge the screen later. + */ + xf86DefaultScreenLimits (scrn, &width, &height, canGrow); + + if (have_outputs == FALSE) { + if (width < NO_OUTPUT_DEFAULT_WIDTH && height < NO_OUTPUT_DEFAULT_HEIGHT) { + width = NO_OUTPUT_DEFAULT_WIDTH; + height = NO_OUTPUT_DEFAULT_HEIGHT; + } + } + + scrn->display->virtualX = width; + scrn->display->virtualY = height; + } + + if (width > scrn->virtualX) + scrn->virtualX = width; + if (height > scrn->virtualY) + scrn->virtualY = height; + + /* + * Make sure the configuration isn't too small. + */ + if (width < config->minWidth || height < config->minHeight) + return FALSE; + + /* + * Limit the crtc config to virtual[XY] if the driver can't grow the + * desktop. + */ + if (!canGrow) + { + xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight, + width, height); + } + + if (have_outputs) { + /* Mirror output modes to scrn mode list */ + xf86SetScrnInfoModes (scrn); + } else { + /* Clear any existing modes from scrn->modes */ + while (scrn->modes != NULL) + xf86DeleteMode(&scrn->modes, scrn->modes); + scrn->modes = xf86ModesAdd(scrn->modes, + xf86CVTMode(width, height, 60, 0, 0)); + } + + + free(crtcs); + free(modes); + return TRUE; +} + +/* + * Check the CRTC we're going to map each output to vs. it's current + * CRTC. If they don't match, we have to disable the output and the CRTC + * since the driver will have to re-route things. + */ +static void +xf86PrepareOutputs (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr output = config->output[o]; +#if RANDR_GET_CRTC_INTERFACE + /* Disable outputs that are unused or will be re-routed */ + if (!output->funcs->get_crtc || + output->crtc != (*output->funcs->get_crtc)(output) || + output->crtc == NULL) +#endif + (*output->funcs->dpms)(output, DPMSModeOff); + } +} + +static void +xf86PrepareCrtcs (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < config->num_crtc; c++) { +#if RANDR_GET_CRTC_INTERFACE + xf86CrtcPtr crtc = config->crtc[c]; + xf86OutputPtr output = NULL; + uint32_t desired_outputs = 0, current_outputs = 0; + int o; + + for (o = 0; o < config->num_output; o++) { + output = config->output[o]; + if (output->crtc == crtc) + desired_outputs |= (1<funcs->get_crtc) { + desired_outputs = 0; + break; + } + if ((*output->funcs->get_crtc)(output) == crtc) + current_outputs |= (1<funcs->dpms)(crtc, DPMSModeOff); +#else + (*crtc->funcs->dpms)(crtc, DPMSModeOff); +#endif + } +} + +/* + * Using the desired mode information in each crtc, set + * modes (used in EnterVT functions, or at server startup) + */ + +Bool +xf86SetDesiredModes (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CrtcPtr crtc = config->crtc[0]; + int c; + + /* A driver with this hook will take care of this */ + if (!crtc->funcs->set_mode_major) { + xf86PrepareOutputs(scrn); + xf86PrepareCrtcs(scrn); + } + + for (c = 0; c < config->num_crtc; c++) + { + xf86OutputPtr output = NULL; + int o; + RRTransformPtr transform; + + crtc = config->crtc[c]; + + /* Skip disabled CRTCs */ + if (!crtc->enabled) + continue; + + if (xf86CompatOutput(scrn) && xf86CompatCrtc(scrn) == crtc) + output = xf86CompatOutput(scrn); + else + { + for (o = 0; o < config->num_output; o++) + if (config->output[o]->crtc == crtc) + { + output = config->output[o]; + break; + } + } + /* paranoia */ + if (!output) + continue; + + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) + { + DisplayModePtr mode = xf86OutputFindClosestMode (output, scrn->currentMode); + + if (!mode) + return FALSE; + crtc->desiredMode = *mode; + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredTransformPresent = FALSE; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (crtc->desiredTransformPresent) + transform = &crtc->desiredTransform; + else + transform = NULL; + if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation, + transform, crtc->desiredX, crtc->desiredY)) + return FALSE; + } + + xf86DisableUnusedFunctions(scrn); + return TRUE; +} + +/** + * In the current world order, there are lists of modes per output, which may + * or may not include the mode that was asked to be set by XFree86's mode + * selection. Find the closest one, in the following preference order: + * + * - Equality + * - Closer in size to the requested mode, but no larger + * - Closer in refresh rate to the requested mode. + */ + +DisplayModePtr +xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired) +{ + DisplayModePtr best = NULL, scan = NULL; + + for (scan = output->probed_modes; scan != NULL; scan = scan->next) + { + /* If there's an exact match, we're done. */ + if (xf86ModesEqual(scan, desired)) { + best = desired; + break; + } + + /* Reject if it's larger than the desired mode. */ + if (scan->HDisplay > desired->HDisplay || + scan->VDisplay > desired->VDisplay) + { + continue; + } + + /* + * If we haven't picked a best mode yet, use the first + * one in the size range + */ + if (best == NULL) + { + best = scan; + continue; + } + + /* Find if it's closer to the right size than the current best + * option. + */ + if ((scan->HDisplay > best->HDisplay && + scan->VDisplay >= best->VDisplay) || + (scan->HDisplay >= best->HDisplay && + scan->VDisplay > best->VDisplay)) + { + best = scan; + continue; + } + + /* Find if it's still closer to the right refresh than the current + * best resolution. + */ + if (scan->HDisplay == best->HDisplay && + scan->VDisplay == best->VDisplay && + (fabs(scan->VRefresh - desired->VRefresh) < + fabs(best->VRefresh - desired->VRefresh))) { + best = scan; + } + } + return best; +} + +/** + * When setting a mode through XFree86-VidModeExtension or XFree86-DGA, + * take the specified mode and apply it to the crtc connected to the compat + * output. Then, find similar modes for the other outputs, as with the + * InitialConfiguration code above. The goal is to clone the desired + * mode across all outputs that are currently active. + */ + +Bool +xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + Bool ok = TRUE; + xf86OutputPtr compat_output; + DisplayModePtr compat_mode = NULL; + int c; + + /* + * Let the compat output drive the final mode selection + */ + compat_output = xf86CompatOutput(pScrn); + if (compat_output) + compat_mode = xf86OutputFindClosestMode (compat_output, desired); + if (compat_mode) + desired = compat_mode; + + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + DisplayModePtr crtc_mode = NULL; + int o; + + if (!crtc->enabled) + continue; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + DisplayModePtr output_mode; + + /* skip outputs not on this crtc */ + if (output->crtc != crtc) + continue; + + if (crtc_mode) + { + output_mode = xf86OutputFindClosestMode (output, crtc_mode); + if (output_mode != crtc_mode) + output->crtc = NULL; + } + else + crtc_mode = xf86OutputFindClosestMode (output, desired); + } + if (!crtc_mode) + { + crtc->enabled = FALSE; + continue; + } + if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0)) + ok = FALSE; + else + { + crtc->desiredMode = *crtc_mode; + crtc->desiredRotation = rotation; + crtc->desiredTransformPresent = FALSE; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + } + xf86DisableUnusedFunctions(pScrn); +#ifdef RANDR_12_INTERFACE + xf86RandR12TellChanged (pScrn->pScreen); +#endif + return ok; +} + + +/** + * Set the DPMS power mode of all outputs and CRTCs. + * + * If the new mode is off, it will turn off outputs and then CRTCs. + * Otherwise, it will affect CRTCs before outputs. + */ +void +xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int i; + + if (!scrn->vtSema) + return; + + if (mode == DPMSModeOff) { + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + if (output->crtc != NULL) + (*output->funcs->dpms) (output, mode); + } + } + + for (i = 0; i < config->num_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; + if (crtc->enabled) + (*crtc->funcs->dpms) (crtc, mode); + } + + if (mode != DPMSModeOff) { + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + if (output->crtc != NULL) + (*output->funcs->dpms) (output, mode); + } + } +} + +/** + * Implement the screensaver by just calling down into the driver DPMS hooks. + * + * Even for monitors with no DPMS support, by the definition of our DPMS hooks, + * the outputs will still get disabled (blanked). + */ +Bool +xf86SaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (xf86IsUnblank(mode)) + xf86DPMSSet(pScrn, DPMSModeOn, 0); + else + xf86DPMSSet(pScrn, DPMSModeOff, 0); + + return TRUE; +} + +/** + * Disable all inactive crtcs and outputs + */ +void +xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int o, c; + + for (o = 0; o < xf86_config->num_output; o++) + { + xf86OutputPtr output = xf86_config->output[o]; + if (!output->crtc) + (*output->funcs->dpms)(output, DPMSModeOff); + } + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (!crtc->enabled) + { + crtc->funcs->dpms(crtc, DPMSModeOff); + memset(&crtc->mode, 0, sizeof(crtc->mode)); + xf86RotateDestroy(crtc); + crtc->active = FALSE; + } + } + if (pScrn->pScreen) + xf86_crtc_notify(pScrn->pScreen); + if (pScrn->ModeSet) + pScrn->ModeSet(pScrn); +} + +#ifdef RANDR_12_INTERFACE + +#define EDID_ATOM_NAME "EDID" + +/** + * Set the RandR EDID property + */ +static void +xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len) +{ + Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME) - 1, TRUE); + + /* This may get called before the RandR resources have been created */ + if (output->randr_output == NULL) + return; + + if (data_len != 0) { + RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8, + PropModeReplace, data_len, data, FALSE, TRUE); + } else { + RRDeleteOutputProperty(output->randr_output, edid_atom); + } +} + +#endif + +/* Pull out a phyiscal size from a detailed timing if available. */ +struct det_phySize_parameter { + xf86OutputPtr output; + ddc_quirk_t quirks; + Bool ret; +}; + +static void handle_detailed_physical_size(struct detailed_monitor_section + *det_mon, void *data) +{ + struct det_phySize_parameter *p; + p = (struct det_phySize_parameter *)data; + + if (p->ret == TRUE ) + return ; + + xf86DetTimingApplyQuirks(det_mon, p->quirks, + p->output->MonInfo->features.hsize, + p->output->MonInfo->features.vsize); + if (det_mon->type == DT && + det_mon->section.d_timings.h_size != 0 && + det_mon->section.d_timings.v_size != 0) { + + p->output->mm_width = det_mon->section.d_timings.h_size; + p->output->mm_height = det_mon->section.d_timings.v_size; + p->ret = TRUE; + } +} + +/** + * Set the EDID information for the specified output + */ +void +xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) +{ + ScrnInfoPtr scrn = output->scrn; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + Bool debug_modes = config->debug_modes || xf86Initialising; +#ifdef RANDR_12_INTERFACE + int size; +#endif + + free(output->MonInfo); + + output->MonInfo = edid_mon; + output->mm_width = 0; + output->mm_height = 0; + + if (debug_modes) { + xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", + output->name); + xf86PrintEDID(edid_mon); + } + + /* Set the DDC properties for the 'compat' output */ + if (output == xf86CompatOutput(scrn)) + xf86SetDDCproperties(scrn, edid_mon); + +#ifdef RANDR_12_INTERFACE + /* Set the RandR output properties */ + size = 0; + if (edid_mon) + { + if (edid_mon->ver.version == 1) { + size = 128; + if (edid_mon->flags & EDID_COMPLETE_RAWDATA) + size += edid_mon->no_sections * 128; + } else if (edid_mon->ver.version == 2) + size = 256; + } + xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size); +#endif + + if (edid_mon) { + + struct det_phySize_parameter p; + p.output = output; + p.quirks = xf86DDCDetectQuirks(scrn->scrnIndex,edid_mon, FALSE); + p.ret = FALSE; + xf86ForEachDetailedBlock(edid_mon, + handle_detailed_physical_size, &p); + + /* if no mm size is available from a detailed timing, check the max size field */ + if ((!output->mm_width || !output->mm_height) && + (edid_mon->features.hsize && edid_mon->features.vsize)) + { + output->mm_width = edid_mon->features.hsize * 10; + output->mm_height = edid_mon->features.vsize * 10; + } + } +} + +/** + * Return the list of modes supported by the EDID information + * stored in 'output' + */ +DisplayModePtr +xf86OutputGetEDIDModes (xf86OutputPtr output) +{ + ScrnInfoPtr scrn = output->scrn; + xf86MonPtr edid_mon = output->MonInfo; + + if (!edid_mon) + return NULL; + return xf86DDCGetModes(scrn->scrnIndex, edid_mon); +} + +/* maybe we should care about DDC1? meh. */ +xf86MonPtr +xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) +{ + ScrnInfoPtr scrn = output->scrn; + xf86MonPtr mon; + + mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE); + if (mon) + xf86DDCApplyQuirks(scrn->scrnIndex, mon); + + return mon; +} + +static char *_xf86ConnectorNames[] = { + "None", "VGA", "DVI-I", "DVI-D", + "DVI-A", "Composite", "S-Video", + "Component", "LFP", "Proprietary", + "HDMI", "DisplayPort", + }; +char * +xf86ConnectorGetName(xf86ConnectorType connector) +{ + return _xf86ConnectorNames[connector]; +} + +static void +x86_crtc_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) +{ + dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1; + dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2; + dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1; + dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2; + + if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2) + dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; +} + +static void +x86_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) +{ + if (crtc->enabled) { + crtc_box->x1 = crtc->x; + crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation); + crtc_box->y1 = crtc->y; + crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation); + } else + crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; +} + +static int +xf86_crtc_box_area(BoxPtr box) +{ + return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1); +} + +/* + * Return the crtc covering 'box'. If two crtcs cover a portion of + * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc + * with greater coverage + */ + +static xf86CrtcPtr +xf86_covering_crtc(ScrnInfoPtr pScrn, + BoxPtr box, + xf86CrtcPtr desired, + BoxPtr crtc_box_ret) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc, best_crtc; + int coverage, best_coverage; + int c; + BoxRec crtc_box, cover_box; + + best_crtc = NULL; + best_coverage = 0; + crtc_box_ret->x1 = 0; + crtc_box_ret->x2 = 0; + crtc_box_ret->y1 = 0; + crtc_box_ret->y2 = 0; + for (c = 0; c < xf86_config->num_crtc; c++) { + crtc = xf86_config->crtc[c]; + x86_crtc_box(crtc, &crtc_box); + x86_crtc_box_intersect(&cover_box, &crtc_box, box); + coverage = xf86_crtc_box_area(&cover_box); + if (coverage && crtc == desired) { + *crtc_box_ret = crtc_box; + return crtc; + } else if (coverage > best_coverage) { + *crtc_box_ret = crtc_box; + best_crtc = crtc; + best_coverage = coverage; + } + } + return best_crtc; +} + +/* + * For overlay video, compute the relevant CRTC and + * clip video to that. + * + * returning FALSE means there was a memory failure of some kind, + * not that the video shouldn't be displayed + */ + +Bool +xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn, + xf86CrtcPtr *crtc_ret, + xf86CrtcPtr desired_crtc, + BoxPtr dst, + INT32 *xa, + INT32 *xb, + INT32 *ya, + INT32 *yb, + RegionPtr reg, + INT32 width, + INT32 height) +{ + Bool ret; + RegionRec crtc_region_local; + RegionPtr crtc_region = reg; + + if (crtc_ret) { + BoxRec crtc_box; + xf86CrtcPtr crtc = xf86_covering_crtc(pScrn, dst, + desired_crtc, + &crtc_box); + + if (crtc) { + RegionInit(&crtc_region_local, &crtc_box, 1); + crtc_region = &crtc_region_local; + RegionIntersect(crtc_region, crtc_region, reg); + } + *crtc_ret = crtc; + } + + ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, + crtc_region, width, height); + + if (crtc_region != reg) + RegionUninit(&crtc_region_local); + + return ret; +} + +xf86_crtc_notify_proc_ptr +xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new) +{ + if (xf86CrtcConfigPrivateIndex != -1) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + xf86_crtc_notify_proc_ptr old; + + old = config->xf86_crtc_notify; + config->xf86_crtc_notify = new; + return old; + } + return NULL; +} + +void +xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old) +{ + if (xf86CrtcConfigPrivateIndex != -1) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + + config->xf86_crtc_notify = old; + } +} + +void +xf86_crtc_notify(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + + if (config->xf86_crtc_notify) + config->xf86_crtc_notify(screen); +} + +Bool +xf86_crtc_supports_gamma(ScrnInfoPtr pScrn) +{ + if (xf86CrtcConfigPrivateIndex != -1) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc; + + /* for multiple drivers loaded we need this */ + if (!xf86_config) + return FALSE; + if (xf86_config->num_crtc == 0) + return FALSE; + crtc = xf86_config->crtc[0]; + + return crtc->funcs->gamma_set != NULL; + } + + return FALSE; +} diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h index e4037142f..68a968cc2 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.h +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h @@ -1,1075 +1,972 @@ -/* - * Copyright © 2006 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ -#ifndef _XF86CRTC_H_ -#define _XF86CRTC_H_ - -#include -#include "randrstr.h" -#if XF86_MODES_RENAME -#include "xf86Rename.h" -#endif -#include "xf86Modes.h" -#include "xf86Cursor.h" -#include "xf86i2c.h" -#include "damage.h" -#include "picturestr.h" - -/* Compat definitions for older X Servers. */ -#ifndef M_T_PREFERRED -#define M_T_PREFERRED 0x08 -#endif -#ifndef M_T_DRIVER -#define M_T_DRIVER 0x40 -#endif -#ifndef M_T_USERPREF -#define M_T_USERPREF 0x80 -#endif -#ifndef HARDWARE_CURSOR_ARGB -#define HARDWARE_CURSOR_ARGB 0x00004000 -#endif - -typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr; -typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr; - -/* define a standard for connector types */ -typedef enum _xf86ConnectorType { - XF86ConnectorNone, - XF86ConnectorVGA, - XF86ConnectorDVI_I, - XF86ConnectorDVI_D, - XF86ConnectorDVI_A, - XF86ConnectorComposite, - XF86ConnectorSvideo, - XF86ConnectorComponent, - XF86ConnectorLFP, - XF86ConnectorProprietary, - XF86ConnectorHDMI, - XF86ConnectorDisplayPort, -} xf86ConnectorType; - -typedef enum _xf86OutputStatus { - XF86OutputStatusConnected, - XF86OutputStatusDisconnected, - XF86OutputStatusUnknown -} xf86OutputStatus; - -typedef enum _xf86CrtcSetFlags { - XF86CrtcSetMode = 1, /* mode */ - XF86CrtcSetOutput = 2, /* outputs */ - XF86CrtcSetOrigin = 4, /* x/y */ - XF86CrtcSetTransform = 8, /* transform */ - XF86CrtcSetRotation = 16, /* rotation */ - XF86CrtcSetProperty = 32, /* output property */ - XF86CrtcSetScanoutPixmap = 64, /* scanout pixmap */ -} xf86CrtcSetFlags; - -typedef struct _xf86CrtcSet { - xf86CrtcSetFlags flags; - DisplayModePtr mode; - Rotation rotation; - RRTransformPtr transform; - int x, y; - PixmapPtr scanout_pixmap; -} xf86CrtcSetRec; - -typedef struct _xf86CrtcFuncs { - /** - * Turns the crtc on/off, or sets intermediate power levels if available. - * - * Unsupported intermediate modes drop to the lower power setting. If the - * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to - * be safe to call mode_set. - */ - void - (*dpms)(xf86CrtcPtr crtc, - int mode); - - /** - * Saves the crtc's state for restoration on VT switch. - */ - void - (*save)(xf86CrtcPtr crtc); - - /** - * Restore's the crtc's state at VT switch. - */ - void - (*restore)(xf86CrtcPtr crtc); - - /** - * Lock CRTC prior to mode setting, mostly for DRI. - * Returns whether unlock is needed - */ - Bool - (*lock) (xf86CrtcPtr crtc); - - /** - * Unlock CRTC after mode setting, mostly for DRI - */ - void - (*unlock) (xf86CrtcPtr crtc); - - /** - * Callback to adjust the mode to be set in the CRTC. - * - * This allows a CRTC to adjust the clock or even the entire set of - * timings, which is used for panels with fixed timings or for - * buses with clock limitations. - */ - Bool - (*mode_fixup)(xf86CrtcPtr crtc, - DisplayModePtr mode, - DisplayModePtr adjusted_mode); - - /** - * Prepare CRTC for an upcoming mode set. - */ - void - (*prepare)(xf86CrtcPtr crtc); - - /** - * Callback for setting up a video mode after fixups have been made. - */ - void - (*mode_set)(xf86CrtcPtr crtc, - DisplayModePtr mode, - DisplayModePtr adjusted_mode, - int x, int y); - - /** - * Commit mode changes to a CRTC - */ - void - (*commit)(xf86CrtcPtr crtc); - - /* Set the color ramps for the CRTC to the given values. */ - void - (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, - int size); - - /** - * Allocate the shadow area, delay the pixmap creation until needed - */ - void * - (*shadow_allocate) (xf86CrtcPtr crtc, int width, int height); - - /** - * Create shadow pixmap for rotation support - */ - PixmapPtr - (*shadow_create) (xf86CrtcPtr crtc, void *data, int width, int height); - - /** - * Destroy shadow pixmap - */ - void - (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data); - - /** - * Set cursor colors - */ - void - (*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg); - - /** - * Set cursor position - */ - void - (*set_cursor_position) (xf86CrtcPtr crtc, int x, int y); - - /** - * Show cursor - */ - void - (*show_cursor) (xf86CrtcPtr crtc); - - /** - * Hide cursor - */ - void - (*hide_cursor) (xf86CrtcPtr crtc); - - /** - * Load monochrome image - */ - void - (*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image); - - /** - * Load ARGB image - */ - void - (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image); - - /** - * Clean up driver-specific bits of the crtc - */ - void - (*destroy) (xf86CrtcPtr crtc); - - /** - * Less fine-grained mode setting entry point for kernel modesetting - */ - Bool - (*set_mode_major)(xf86CrtcPtr crtc, DisplayModePtr mode, - Rotation rotation, int x, int y); - - /** - * Callback for panning. Doesn't change the mode. - * Added in ABI version 2 - */ - void - (*set_origin)(xf86CrtcPtr crtc, int x, int y); - - /** - * General mode setting entry point that does everything - */ - Bool - (*set)(xf86CrtcPtr crtc, xf86CrtcSetFlags flags); - -} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr; - -#define XF86_CRTC_VERSION 3 - -struct _xf86Crtc { - /** - * ABI versioning - */ - int version; - - /** - * Associated ScrnInfo - */ - ScrnInfoPtr scrn; - - /** - * Desired state of this CRTC - * - * Set when this CRTC should be driving one or more outputs - */ - Bool enabled; - - /** - * Active mode - * - * This reflects the mode as set in the CRTC currently - * It will be cleared when the VT is not active or - * during server startup - */ - DisplayModeRec mode; - Rotation rotation; - PixmapPtr rotatedPixmap; - void *rotatedData; - PixmapPtr scanoutPixmap; - - /** - * Position on screen - * - * Locates this CRTC within the frame buffer - */ - int x, y; - - /** - * Desired mode - * - * This is set to the requested mode, independent of - * whether the VT is active. In particular, it receives - * the startup configured mode and saves the active mode - * on VT switch. - */ - DisplayModeRec desiredMode; - Rotation desiredRotation; - int desiredX, desiredY; - - /** crtc-specific functions */ - const xf86CrtcFuncsRec *funcs; - - /** - * Driver private - * - * Holds driver-private information - */ - void *driver_private; - -#ifdef RANDR_12_INTERFACE - /** - * RandR crtc - * - * When RandR 1.2 is available, this - * points at the associated crtc object - */ - RRCrtcPtr randr_crtc; -#else - void *randr_crtc; -#endif - - /** - * Current cursor is ARGB - */ - Bool cursor_argb; - /** - * Track whether cursor is within CRTC range - */ - Bool cursor_in_range; - /** - * Track state of cursor associated with this CRTC - */ - Bool cursor_shown; - - /** - * Current transformation matrix - */ - PictTransform crtc_to_framebuffer; - /* framebuffer_to_crtc was removed in ABI 2 */ - struct pict_f_transform f_crtc_to_framebuffer; /* ABI 2 */ - struct pict_f_transform f_framebuffer_to_crtc; /* ABI 2 */ - PictFilterPtr filter; /* ABI 2 */ - xFixed *params; /* ABI 2 */ - int nparams; /* ABI 2 */ - int filter_width; /* ABI 2 */ - int filter_height; /* ABI 2 */ - Bool transform_in_use; - Bool sprite_transform_in_use; - RRTransformRec transform; /* ABI 2 */ - Bool transformPresent; /* ABI 2 */ - RRTransformRec desiredTransform; /* ABI 2 */ - Bool desiredTransformPresent; /* ABI 2 */ - /** - * Bounding box in screen space - */ - BoxRec bounds; - /** - * Panning: - * TotalArea: total panning area, larger than CRTC's size - * TrackingArea: Area of the pointer for which the CRTC is panned - * border: Borders of the displayed CRTC area which induces panning if the pointer reaches them - * Added in ABI version 2 - */ - BoxRec panningTotalArea; - BoxRec panningTrackingArea; - INT16 panningBorder[4]; - - /** - * Current gamma, especially useful after initial config. - * Added in ABI version 3 - */ - CARD16 *gamma_red; - CARD16 *gamma_green; - CARD16 *gamma_blue; - int gamma_size; - - /** - * Actual state of this CRTC - * - * Set to TRUE after modesetting, set to FALSE if no outputs are connected - * Added in ABI version 3 - */ - Bool active; - /** - * Clear the shadow - */ - Bool shadowClear; - - /** - * Sprite position transforms - */ - - /* Transform a screen coordinate to a crtc coordinate */ - struct pixman_f_transform f_screen_to_crtc; - - /* The user-specified portion of the screen to crtc conversion */ - struct pixman_f_transform user_sprite_position_transform; - - /* Transform a hardware cursor coordinate to a cursor coordinate */ - struct pixman_f_transform f_crtc_to_cursor; - - /* The user-specified portion of the cursor to hardware transform */ - struct pixman_f_transform user_sprite_image_transform; -}; - -typedef struct _xf86OutputFuncs { - /** - * Called to allow the output a chance to create properties after the - * RandR objects have been created. - */ - void - (*create_resources)(xf86OutputPtr output); - - /** - * Turns the output on/off, or sets intermediate power levels if available. - * - * Unsupported intermediate modes drop to the lower power setting. If the - * mode is DPMSModeOff, the output must be disabled, as the DPLL may be - * disabled afterwards. - */ - void - (*dpms)(xf86OutputPtr output, - int mode); - - /** - * Saves the output's state for restoration on VT switch. - */ - void - (*save)(xf86OutputPtr output); - - /** - * Restore's the output's state at VT switch. - */ - void - (*restore)(xf86OutputPtr output); - - /** - * Callback for testing a video mode for a given output. - * - * This function should only check for cases where a mode can't be supported - * on the output specifically, and not represent generic CRTC limitations. - * - * \return MODE_OK if the mode is valid, or another MODE_* otherwise. - */ - int - (*mode_valid)(xf86OutputPtr output, - DisplayModePtr pMode); - - /** - * Callback to adjust the mode to be set in the CRTC. - * - * This allows an output to adjust the clock or even the entire set of - * timings, which is used for panels with fixed timings or for - * buses with clock limitations. - */ - Bool - (*mode_fixup)(xf86OutputPtr output, - DisplayModePtr mode, - DisplayModePtr adjusted_mode); - - /** - * Callback for preparing mode changes on an output - */ - void - (*prepare)(xf86OutputPtr output); - - /** - * Callback for committing mode changes on an output - */ - void - (*commit)(xf86OutputPtr output); - - /** - * Callback for setting up a video mode after fixups have been made. - * - * This is only called while the output is disabled. The dpms callback - * must be all that's necessary for the output, to turn the output on - * after this function is called. - */ - void - (*mode_set)(xf86OutputPtr output, - DisplayModePtr mode, - DisplayModePtr adjusted_mode); - - /** - * Probe for a connected output, and return detect_status. - */ - xf86OutputStatus - (*detect)(xf86OutputPtr output); - - /** - * Query the device for the modes it provides. - * - * This function may also update MonInfo, mm_width, and mm_height. - * - * \return singly-linked list of modes or NULL if no modes found. - */ - DisplayModePtr - (*get_modes)(xf86OutputPtr output); - -#ifdef RANDR_12_INTERFACE - /** - * Callback when an output's property has changed. - */ - Bool - (*set_property)(xf86OutputPtr output, - Atom property, - RRPropertyValuePtr value); -#endif -#ifdef RANDR_13_INTERFACE - /** - * Callback to get an updated property value - */ - Bool - (*get_property)(xf86OutputPtr output, - Atom property); -#endif -#ifdef RANDR_GET_CRTC_INTERFACE - /** - * Callback to get current CRTC for a given output - */ - xf86CrtcPtr - (*get_crtc)(xf86OutputPtr output); -#endif - /** - * Clean up driver-specific bits of the output - */ - void - (*destroy) (xf86OutputPtr output); -} xf86OutputFuncsRec, *xf86OutputFuncsPtr; - - -#define XF86_OUTPUT_VERSION 2 - -struct _xf86Output { - /** - * ABI versioning - */ - int version; - - /** - * Associated ScrnInfo - */ - ScrnInfoPtr scrn; - - /** - * Currently connected crtc (if any) - * - * If this output is not in use, this field will be NULL. - */ - xf86CrtcPtr crtc; - - /** - * Possible CRTCs for this output as a mask of crtc indices - */ - CARD32 possible_crtcs; - - /** - * Possible outputs to share the same CRTC as a mask of output indices - */ - CARD32 possible_clones; - - /** - * Whether this output can support interlaced modes - */ - Bool interlaceAllowed; - - /** - * Whether this output can support double scan modes - */ - Bool doubleScanAllowed; - - /** - * List of available modes on this output. - * - * This should be the list from get_modes(), plus perhaps additional - * compatible modes added later. - */ - DisplayModePtr probed_modes; - - /** - * Options parsed from the related monitor section - */ - OptionInfoPtr options; - - /** - * Configured monitor section - */ - XF86ConfMonitorPtr conf_monitor; - - /** - * Desired initial position - */ - int initial_x, initial_y; - - /** - * Desired initial rotation - */ - Rotation initial_rotation; - - /** - * Current connection status - * - * This indicates whether a monitor is known to be connected - * to this output or not, or whether there is no way to tell - */ - xf86OutputStatus status; - - /** EDID monitor information */ - xf86MonPtr MonInfo; - - /** subpixel order */ - int subpixel_order; - - /** Physical size of the currently attached output device. */ - int mm_width, mm_height; - - /** Output name */ - char *name; - - /** output-specific functions */ - const xf86OutputFuncsRec *funcs; - - /** driver private information */ - void *driver_private; - - /** Whether to use the old per-screen Monitor config section */ - Bool use_screen_monitor; - -#ifdef RANDR_12_INTERFACE - /** - * RandR 1.2 output structure. - * - * When RandR 1.2 is available, this points at the associated - * RandR output structure and is created when this output is created - */ - RROutputPtr randr_output; -#else - void *randr_output; -#endif - /** - * Desired initial panning - * Added in ABI version 2 - */ - BoxRec initialTotalArea; - BoxRec initialTrackingArea; - INT16 initialBorder[4]; -}; - -typedef enum _xf86SetConfigResponse { - xf86SetConfigFailed, /* set_config failed */ - xf86SetConfigChecked, /* set_config validated the configuration */ - xf86SetConfigDone, /* set_config finished the work */ -} xf86SetConfigResponse; - -typedef struct _xf86CrtcSetConfig { - xf86CrtcPtr crtc; - int x, y; - DisplayModeRec mode; - Rotation rotation; - int numOutputs; - xf86OutputPtr *outputs; - struct pict_f_transform sprite_position_transform; - struct pict_f_transform sprite_image_transform; - - /* Probably want some internal structure for the pixmap so that - * this can be set before the server is running - */ - PixmapPtr pixmap; - int pixmap_x, pixmap_y; -} xf86CrtcSetConfigRec, *xf86CrtcSetConfigPtr; - -typedef struct _xf86CrtcScanoutFormat { - int depth; - int bitsPerPixel; - int maxWidth, maxHeight; - Rotation rotations; - PictFormatShort format; -} xf86CrtcScanoutFormat; - -typedef struct _xf86CrtcConfigFuncs { - /** - * Requests that the driver resize the screen. - * - * The driver is responsible for updating scrn->virtualX and scrn->virtualY. - * If the requested size cannot be set, the driver should leave those values - * alone and return FALSE. - * - * A naive driver that cannot reallocate the screen may simply change - * virtual[XY]. A more advanced driver will want to also change the - * devPrivate.ptr and devKind of the screen pixmap, update any offscreen - * pixmaps it may have moved, and change pScrn->displayWidth. - */ - Bool - (*resize)(ScrnInfoPtr scrn, - int width, - int height); - - xf86SetConfigResponse - (*set_config) (ScrnInfoPtr scrn, - RRScreenConfigPtr screen_config, - xf86CrtcSetConfigPtr crtc_configs, - int num_configs); - - /** - * Create a scanout pixmap - */ - PixmapPtr - (*create_scanout_pixmap)(ScrnInfoPtr scrn, - int width, - int height, - Rotation rotations, - xf86CrtcScanoutFormat *format); - -} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr; - -typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen); - -typedef struct _xf86CrtcConfig { - int num_output; - xf86OutputPtr *output; - /** - * compat_output is used whenever we deal - * with legacy code that only understands a single - * output. pScrn->modes will be loaded from this output, - * adjust frame will whack this output, etc. - */ - int compat_output; - - int num_crtc; - xf86CrtcPtr *crtc; - - int minWidth, minHeight; - int maxWidth, maxHeight; - - /* For crtc-based rotation */ - DamagePtr rotation_damage; - Bool rotation_damage_registered; - - /* DGA */ - unsigned int dga_flags; - unsigned long dga_address; - DGAModePtr dga_modes; - int dga_nmode; - int dga_width, dga_height, dga_stride; - DisplayModePtr dga_save_mode; - - const xf86CrtcConfigFuncsRec *funcs; - - CreateScreenResourcesProcPtr CreateScreenResources; - - CloseScreenProcPtr CloseScreen; - - /* Cursor information */ - xf86CursorInfoPtr cursor_info; - CursorPtr cursor; - CARD8 *cursor_image; - Bool cursor_on; - CARD32 cursor_fg, cursor_bg; - - /** - * Options parsed from the related device section - */ - OptionInfoPtr options; - - Bool debug_modes; - - /* wrap screen BlockHandler for rotation */ - ScreenBlockHandlerProcPtr BlockHandler; - - /* callback when crtc configuration changes */ - xf86_crtc_notify_proc_ptr xf86_crtc_notify; - - /* - * Supported scanout pixmap formats - */ - int num_scanout_formats; - xf86CrtcScanoutFormat *scanout_formats; -} xf86CrtcConfigRec, *xf86CrtcConfigPtr; - -extern _X_EXPORT int xf86CrtcConfigPrivateIndex; - -#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr)) - -static _X_INLINE xf86OutputPtr -xf86CompatOutput(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - return config->output[config->compat_output]; -} - -static _X_INLINE xf86CrtcPtr -xf86CompatCrtc(ScrnInfoPtr pScrn) -{ - xf86OutputPtr compat_output = xf86CompatOutput(pScrn); - if (!compat_output) - return NULL; - return compat_output->crtc; -} - -static _X_INLINE RRCrtcPtr -xf86CompatRRCrtc(ScrnInfoPtr pScrn) -{ - xf86CrtcPtr compat_crtc = xf86CompatCrtc(pScrn); - if (!compat_crtc) - return NULL; - return compat_crtc->randr_crtc; -} - - -/* - * Initialize xf86CrtcConfig structure - */ - -extern _X_EXPORT void -xf86CrtcConfigInit (ScrnInfoPtr scrn, - const xf86CrtcConfigFuncsRec *funcs); - -extern _X_EXPORT void -xf86CrtcSetSizeRange (ScrnInfoPtr scrn, - int minWidth, int minHeight, - int maxWidth, int maxHeight); - -extern _X_EXPORT void -xf86CrtcSetScanoutFormats (ScrnInfoPtr scrn, - int num_formats, - xf86CrtcScanoutFormat *formats); - -/* - * Crtc functions - */ -extern _X_EXPORT xf86CrtcPtr -xf86CrtcCreate (ScrnInfoPtr scrn, - const xf86CrtcFuncsRec *funcs); - -extern _X_EXPORT void -xf86CrtcDestroy (xf86CrtcPtr crtc); - -/** - * Change a crtc configuration (modes, outputs, etc) - */ - -extern _X_EXPORT Bool -xf86CrtcSet (xf86CrtcPtr crtc, xf86CrtcSetRec *set); - -extern _X_EXPORT void -xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y); - -/* - * Assign crtc rotation during mode set - */ -extern _X_EXPORT Bool -xf86CrtcRotate (xf86CrtcPtr crtc); - - -/* - * Update cursor transform matrices after user changes - * This is just the cursor subset of xf86CrtcRotate - */ -extern _X_EXPORT void -xf86CrtcRotateCursor (xf86CrtcPtr crtc); - -/* - * Clean up any rotation data, used when a crtc is turned off - * as well as when rotation is disabled. - */ -extern _X_EXPORT void -xf86RotateDestroy (xf86CrtcPtr crtc); - -/* - * free shadow memory allocated for all crtcs - */ -extern _X_EXPORT void -xf86RotateFreeShadow(ScrnInfoPtr pScrn); - -/* - * Clean up rotation during CloseScreen - */ -extern _X_EXPORT void -xf86RotateCloseScreen (ScreenPtr pScreen); - -/** - * Return whether any output is assigned to the crtc - */ -extern _X_EXPORT Bool -xf86CrtcInUse (xf86CrtcPtr crtc); - -/* - * Output functions - */ -extern _X_EXPORT xf86OutputPtr -xf86OutputCreate (ScrnInfoPtr scrn, - const xf86OutputFuncsRec *funcs, - const char *name); - -extern _X_EXPORT void -xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor); - -extern _X_EXPORT Bool -xf86OutputRename (xf86OutputPtr output, const char *name); - -extern _X_EXPORT void -xf86OutputDestroy (xf86OutputPtr output); - -extern _X_EXPORT void -xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY); - -extern _X_EXPORT void -xf86SetScrnInfoModes (ScrnInfoPtr pScrn); - -#ifdef RANDR_13_INTERFACE -# define ScreenInitRetType int -#else -# define ScreenInitRetType Bool -#endif - -extern _X_EXPORT ScreenInitRetType -xf86CrtcScreenInit (ScreenPtr pScreen); - -extern _X_EXPORT Bool -xf86InitialConfiguration (ScrnInfoPtr pScrn, Bool canGrow); - -extern _X_EXPORT void -xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); - -extern _X_EXPORT Bool -xf86SaveScreen(ScreenPtr pScreen, int mode); - -extern _X_EXPORT void -xf86DisableUnusedFunctions(ScrnInfoPtr pScrn); - -extern _X_EXPORT DisplayModePtr -xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired); - -extern _X_EXPORT Bool -xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation); - -/** - * Set the EDID information for the specified output - */ -extern _X_EXPORT void -xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon); - -/** - * Return the list of modes supported by the EDID information - * stored in 'output' - */ -extern _X_EXPORT DisplayModePtr -xf86OutputGetEDIDModes (xf86OutputPtr output); - -extern _X_EXPORT xf86MonPtr -xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus); - -/** - * Initialize dga for this screen - */ - -#ifdef XFreeXDGA -extern _X_EXPORT Bool -xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address); - -/* this is the real function, used only internally */ -_X_INTERNAL Bool -_xf86_di_dga_init_internal (ScreenPtr pScreen); - -/** - * Re-initialize dga for this screen (as when the set of modes changes) - */ - -extern _X_EXPORT Bool -xf86DiDGAReInit (ScreenPtr pScreen); -#endif - -/* This is the real function, used only internally */ -_X_INTERNAL Bool -_xf86_di_dga_reinit_internal (ScreenPtr pScreen); - -/* - * Set the subpixel order reported for the screen using - * the information from the outputs - */ - -extern _X_EXPORT void -xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen); - -/* - * Get a standard string name for a connector type - */ -extern _X_EXPORT char * -xf86ConnectorGetName(xf86ConnectorType connector); - -/* - * Using the desired mode information in each crtc, set - * modes (used in EnterVT functions, or at server startup) - */ - -extern _X_EXPORT Bool -xf86SetDesiredModes (ScrnInfoPtr pScrn); - -/** - * Initialize the CRTC-based cursor code. CRTC function vectors must - * contain relevant cursor setting functions. - * - * Driver should call this from ScreenInit function - */ -extern _X_EXPORT Bool -xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags); - -/** - * Called when anything on the screen is reconfigured. - * - * Reloads cursor images as needed, then adjusts cursor positions. - * - * Driver should call this from crtc commit function. - */ -extern _X_EXPORT void -xf86_reload_cursors (ScreenPtr screen); - -/** - * Called from EnterVT to turn the cursors back on - */ -extern _X_EXPORT void -xf86_show_cursors (ScrnInfoPtr scrn); - -/** - * Called by the driver to turn cursors off - */ -extern _X_EXPORT void -xf86_hide_cursors (ScrnInfoPtr scrn); - -/** - * Clean up CRTC-based cursor code. Driver must call this at CloseScreen time. - */ -extern _X_EXPORT void -xf86_cursors_fini (ScreenPtr screen); - -/* - * For overlay video, compute the relevant CRTC and - * clip video to that. - * wraps xf86XVClipVideoHelper() - */ - -extern _X_EXPORT Bool -xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn, - xf86CrtcPtr *crtc_ret, - xf86CrtcPtr desired_crtc, - BoxPtr dst, - INT32 *xa, - INT32 *xb, - INT32 *ya, - INT32 *yb, - RegionPtr reg, - INT32 width, - INT32 height); - -extern _X_EXPORT xf86_crtc_notify_proc_ptr -xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new); - -extern _X_EXPORT void -xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old); - -extern _X_EXPORT void -xf86_crtc_notify(ScreenPtr pScreen); - -/** - * Gamma - */ - -extern _X_EXPORT Bool -xf86_crtc_supports_gamma(ScrnInfoPtr pScrn); - -#endif /* _XF86CRTC_H_ */ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ +#ifndef _XF86CRTC_H_ +#define _XF86CRTC_H_ + +#include +#include "randrstr.h" +#if XF86_MODES_RENAME +#include "xf86Rename.h" +#endif +#include "xf86Modes.h" +#include "xf86Cursor.h" +#include "xf86i2c.h" +#include "damage.h" +#include "picturestr.h" + +/* Compat definitions for older X Servers. */ +#ifndef M_T_PREFERRED +#define M_T_PREFERRED 0x08 +#endif +#ifndef M_T_DRIVER +#define M_T_DRIVER 0x40 +#endif +#ifndef M_T_USERPREF +#define M_T_USERPREF 0x80 +#endif +#ifndef HARDWARE_CURSOR_ARGB +#define HARDWARE_CURSOR_ARGB 0x00004000 +#endif + +typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr; +typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr; + +/* define a standard for connector types */ +typedef enum _xf86ConnectorType { + XF86ConnectorNone, + XF86ConnectorVGA, + XF86ConnectorDVI_I, + XF86ConnectorDVI_D, + XF86ConnectorDVI_A, + XF86ConnectorComposite, + XF86ConnectorSvideo, + XF86ConnectorComponent, + XF86ConnectorLFP, + XF86ConnectorProprietary, + XF86ConnectorHDMI, + XF86ConnectorDisplayPort, +} xf86ConnectorType; + +typedef enum _xf86OutputStatus { + XF86OutputStatusConnected, + XF86OutputStatusDisconnected, + XF86OutputStatusUnknown +} xf86OutputStatus; + +typedef struct _xf86CrtcFuncs { + /** + * Turns the crtc on/off, or sets intermediate power levels if available. + * + * Unsupported intermediate modes drop to the lower power setting. If the + * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to + * be safe to call mode_set. + */ + void + (*dpms)(xf86CrtcPtr crtc, + int mode); + + /** + * Saves the crtc's state for restoration on VT switch. + */ + void + (*save)(xf86CrtcPtr crtc); + + /** + * Restore's the crtc's state at VT switch. + */ + void + (*restore)(xf86CrtcPtr crtc); + + /** + * Lock CRTC prior to mode setting, mostly for DRI. + * Returns whether unlock is needed + */ + Bool + (*lock) (xf86CrtcPtr crtc); + + /** + * Unlock CRTC after mode setting, mostly for DRI + */ + void + (*unlock) (xf86CrtcPtr crtc); + + /** + * Callback to adjust the mode to be set in the CRTC. + * + * This allows a CRTC to adjust the clock or even the entire set of + * timings, which is used for panels with fixed timings or for + * buses with clock limitations. + */ + Bool + (*mode_fixup)(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode); + + /** + * Prepare CRTC for an upcoming mode set. + */ + void + (*prepare)(xf86CrtcPtr crtc); + + /** + * Callback for setting up a video mode after fixups have been made. + */ + void + (*mode_set)(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode, + int x, int y); + + /** + * Commit mode changes to a CRTC + */ + void + (*commit)(xf86CrtcPtr crtc); + + /* Set the color ramps for the CRTC to the given values. */ + void + (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, + int size); + + /** + * Allocate the shadow area, delay the pixmap creation until needed + */ + void * + (*shadow_allocate) (xf86CrtcPtr crtc, int width, int height); + + /** + * Create shadow pixmap for rotation support + */ + PixmapPtr + (*shadow_create) (xf86CrtcPtr crtc, void *data, int width, int height); + + /** + * Destroy shadow pixmap + */ + void + (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data); + + /** + * Set cursor colors + */ + void + (*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg); + + /** + * Set cursor position + */ + void + (*set_cursor_position) (xf86CrtcPtr crtc, int x, int y); + + /** + * Show cursor + */ + void + (*show_cursor) (xf86CrtcPtr crtc); + + /** + * Hide cursor + */ + void + (*hide_cursor) (xf86CrtcPtr crtc); + + /** + * Load monochrome image + */ + void + (*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image); + + /** + * Load ARGB image + */ + void + (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image); + + /** + * Clean up driver-specific bits of the crtc + */ + void + (*destroy) (xf86CrtcPtr crtc); + + /** + * Less fine-grained mode setting entry point for kernel modesetting + */ + Bool + (*set_mode_major)(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y); + + /** + * Callback for panning. Doesn't change the mode. + * Added in ABI version 2 + */ + void + (*set_origin)(xf86CrtcPtr crtc, int x, int y); + +} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr; + +#define XF86_CRTC_VERSION 3 + +struct _xf86Crtc { + /** + * ABI versioning + */ + int version; + + /** + * Associated ScrnInfo + */ + ScrnInfoPtr scrn; + + /** + * Desired state of this CRTC + * + * Set when this CRTC should be driving one or more outputs + */ + Bool enabled; + + /** + * Active mode + * + * This reflects the mode as set in the CRTC currently + * It will be cleared when the VT is not active or + * during server startup + */ + DisplayModeRec mode; + Rotation rotation; + PixmapPtr rotatedPixmap; + void *rotatedData; + + /** + * Position on screen + * + * Locates this CRTC within the frame buffer + */ + int x, y; + + /** + * Desired mode + * + * This is set to the requested mode, independent of + * whether the VT is active. In particular, it receives + * the startup configured mode and saves the active mode + * on VT switch. + */ + DisplayModeRec desiredMode; + Rotation desiredRotation; + int desiredX, desiredY; + + /** crtc-specific functions */ + const xf86CrtcFuncsRec *funcs; + + /** + * Driver private + * + * Holds driver-private information + */ + void *driver_private; + +#ifdef RANDR_12_INTERFACE + /** + * RandR crtc + * + * When RandR 1.2 is available, this + * points at the associated crtc object + */ + RRCrtcPtr randr_crtc; +#else + void *randr_crtc; +#endif + + /** + * Current cursor is ARGB + */ + Bool cursor_argb; + /** + * Track whether cursor is within CRTC range + */ + Bool cursor_in_range; + /** + * Track state of cursor associated with this CRTC + */ + Bool cursor_shown; + + /** + * Current transformation matrix + */ + PictTransform crtc_to_framebuffer; + /* framebuffer_to_crtc was removed in ABI 2 */ + struct pict_f_transform f_crtc_to_framebuffer; /* ABI 2 */ + struct pict_f_transform f_framebuffer_to_crtc; /* ABI 2 */ + PictFilterPtr filter; /* ABI 2 */ + xFixed *params; /* ABI 2 */ + int nparams; /* ABI 2 */ + int filter_width; /* ABI 2 */ + int filter_height; /* ABI 2 */ + Bool transform_in_use; + RRTransformRec transform; /* ABI 2 */ + Bool transformPresent; /* ABI 2 */ + RRTransformRec desiredTransform; /* ABI 2 */ + Bool desiredTransformPresent; /* ABI 2 */ + /** + * Bounding box in screen space + */ + BoxRec bounds; + /** + * Panning: + * TotalArea: total panning area, larger than CRTC's size + * TrackingArea: Area of the pointer for which the CRTC is panned + * border: Borders of the displayed CRTC area which induces panning if the pointer reaches them + * Added in ABI version 2 + */ + BoxRec panningTotalArea; + BoxRec panningTrackingArea; + INT16 panningBorder[4]; + + /** + * Current gamma, especially useful after initial config. + * Added in ABI version 3 + */ + CARD16 *gamma_red; + CARD16 *gamma_green; + CARD16 *gamma_blue; + int gamma_size; + + /** + * Actual state of this CRTC + * + * Set to TRUE after modesetting, set to FALSE if no outputs are connected + * Added in ABI version 3 + */ + Bool active; + /** + * Clear the shadow + */ + Bool shadowClear; +}; + +typedef struct _xf86OutputFuncs { + /** + * Called to allow the output a chance to create properties after the + * RandR objects have been created. + */ + void + (*create_resources)(xf86OutputPtr output); + + /** + * Turns the output on/off, or sets intermediate power levels if available. + * + * Unsupported intermediate modes drop to the lower power setting. If the + * mode is DPMSModeOff, the output must be disabled, as the DPLL may be + * disabled afterwards. + */ + void + (*dpms)(xf86OutputPtr output, + int mode); + + /** + * Saves the output's state for restoration on VT switch. + */ + void + (*save)(xf86OutputPtr output); + + /** + * Restore's the output's state at VT switch. + */ + void + (*restore)(xf86OutputPtr output); + + /** + * Callback for testing a video mode for a given output. + * + * This function should only check for cases where a mode can't be supported + * on the output specifically, and not represent generic CRTC limitations. + * + * \return MODE_OK if the mode is valid, or another MODE_* otherwise. + */ + int + (*mode_valid)(xf86OutputPtr output, + DisplayModePtr pMode); + + /** + * Callback to adjust the mode to be set in the CRTC. + * + * This allows an output to adjust the clock or even the entire set of + * timings, which is used for panels with fixed timings or for + * buses with clock limitations. + */ + Bool + (*mode_fixup)(xf86OutputPtr output, + DisplayModePtr mode, + DisplayModePtr adjusted_mode); + + /** + * Callback for preparing mode changes on an output + */ + void + (*prepare)(xf86OutputPtr output); + + /** + * Callback for committing mode changes on an output + */ + void + (*commit)(xf86OutputPtr output); + + /** + * Callback for setting up a video mode after fixups have been made. + * + * This is only called while the output is disabled. The dpms callback + * must be all that's necessary for the output, to turn the output on + * after this function is called. + */ + void + (*mode_set)(xf86OutputPtr output, + DisplayModePtr mode, + DisplayModePtr adjusted_mode); + + /** + * Probe for a connected output, and return detect_status. + */ + xf86OutputStatus + (*detect)(xf86OutputPtr output); + + /** + * Query the device for the modes it provides. + * + * This function may also update MonInfo, mm_width, and mm_height. + * + * \return singly-linked list of modes or NULL if no modes found. + */ + DisplayModePtr + (*get_modes)(xf86OutputPtr output); + +#ifdef RANDR_12_INTERFACE + /** + * Callback when an output's property has changed. + */ + Bool + (*set_property)(xf86OutputPtr output, + Atom property, + RRPropertyValuePtr value); +#endif +#ifdef RANDR_13_INTERFACE + /** + * Callback to get an updated property value + */ + Bool + (*get_property)(xf86OutputPtr output, + Atom property); +#endif +#ifdef RANDR_GET_CRTC_INTERFACE + /** + * Callback to get current CRTC for a given output + */ + xf86CrtcPtr + (*get_crtc)(xf86OutputPtr output); +#endif + /** + * Clean up driver-specific bits of the output + */ + void + (*destroy) (xf86OutputPtr output); +} xf86OutputFuncsRec, *xf86OutputFuncsPtr; + + +#define XF86_OUTPUT_VERSION 2 + +struct _xf86Output { + /** + * ABI versioning + */ + int version; + + /** + * Associated ScrnInfo + */ + ScrnInfoPtr scrn; + + /** + * Currently connected crtc (if any) + * + * If this output is not in use, this field will be NULL. + */ + xf86CrtcPtr crtc; + + /** + * Possible CRTCs for this output as a mask of crtc indices + */ + CARD32 possible_crtcs; + + /** + * Possible outputs to share the same CRTC as a mask of output indices + */ + CARD32 possible_clones; + + /** + * Whether this output can support interlaced modes + */ + Bool interlaceAllowed; + + /** + * Whether this output can support double scan modes + */ + Bool doubleScanAllowed; + + /** + * List of available modes on this output. + * + * This should be the list from get_modes(), plus perhaps additional + * compatible modes added later. + */ + DisplayModePtr probed_modes; + + /** + * Options parsed from the related monitor section + */ + OptionInfoPtr options; + + /** + * Configured monitor section + */ + XF86ConfMonitorPtr conf_monitor; + + /** + * Desired initial position + */ + int initial_x, initial_y; + + /** + * Desired initial rotation + */ + Rotation initial_rotation; + + /** + * Current connection status + * + * This indicates whether a monitor is known to be connected + * to this output or not, or whether there is no way to tell + */ + xf86OutputStatus status; + + /** EDID monitor information */ + xf86MonPtr MonInfo; + + /** subpixel order */ + int subpixel_order; + + /** Physical size of the currently attached output device. */ + int mm_width, mm_height; + + /** Output name */ + char *name; + + /** output-specific functions */ + const xf86OutputFuncsRec *funcs; + + /** driver private information */ + void *driver_private; + + /** Whether to use the old per-screen Monitor config section */ + Bool use_screen_monitor; + +#ifdef RANDR_12_INTERFACE + /** + * RandR 1.2 output structure. + * + * When RandR 1.2 is available, this points at the associated + * RandR output structure and is created when this output is created + */ + RROutputPtr randr_output; +#else + void *randr_output; +#endif + /** + * Desired initial panning + * Added in ABI version 2 + */ + BoxRec initialTotalArea; + BoxRec initialTrackingArea; + INT16 initialBorder[4]; +}; + +typedef struct _xf86CrtcConfigFuncs { + /** + * Requests that the driver resize the screen. + * + * The driver is responsible for updating scrn->virtualX and scrn->virtualY. + * If the requested size cannot be set, the driver should leave those values + * alone and return FALSE. + * + * A naive driver that cannot reallocate the screen may simply change + * virtual[XY]. A more advanced driver will want to also change the + * devPrivate.ptr and devKind of the screen pixmap, update any offscreen + * pixmaps it may have moved, and change pScrn->displayWidth. + */ + Bool + (*resize)(ScrnInfoPtr scrn, + int width, + int height); +} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr; + +typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen); + +typedef struct _xf86CrtcConfig { + int num_output; + xf86OutputPtr *output; + /** + * compat_output is used whenever we deal + * with legacy code that only understands a single + * output. pScrn->modes will be loaded from this output, + * adjust frame will whack this output, etc. + */ + int compat_output; + + int num_crtc; + xf86CrtcPtr *crtc; + + int minWidth, minHeight; + int maxWidth, maxHeight; + + /* For crtc-based rotation */ + DamagePtr rotation_damage; + Bool rotation_damage_registered; + + /* DGA */ + unsigned int dga_flags; + unsigned long dga_address; + DGAModePtr dga_modes; + int dga_nmode; + int dga_width, dga_height, dga_stride; + DisplayModePtr dga_save_mode; + + const xf86CrtcConfigFuncsRec *funcs; + + CreateScreenResourcesProcPtr CreateScreenResources; + + CloseScreenProcPtr CloseScreen; + + /* Cursor information */ + xf86CursorInfoPtr cursor_info; + CursorPtr cursor; + CARD8 *cursor_image; + Bool cursor_on; + CARD32 cursor_fg, cursor_bg; + + /** + * Options parsed from the related device section + */ + OptionInfoPtr options; + + Bool debug_modes; + + /* wrap screen BlockHandler for rotation */ + ScreenBlockHandlerProcPtr BlockHandler; + + /* callback when crtc configuration changes */ + xf86_crtc_notify_proc_ptr xf86_crtc_notify; + +} xf86CrtcConfigRec, *xf86CrtcConfigPtr; + +extern _X_EXPORT int xf86CrtcConfigPrivateIndex; + +#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr)) + +static _X_INLINE xf86OutputPtr +xf86CompatOutput(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + return config->output[config->compat_output]; +} + +static _X_INLINE xf86CrtcPtr +xf86CompatCrtc(ScrnInfoPtr pScrn) +{ + xf86OutputPtr compat_output = xf86CompatOutput(pScrn); + if (!compat_output) + return NULL; + return compat_output->crtc; +} + +static _X_INLINE RRCrtcPtr +xf86CompatRRCrtc(ScrnInfoPtr pScrn) +{ + xf86CrtcPtr compat_crtc = xf86CompatCrtc(pScrn); + if (!compat_crtc) + return NULL; + return compat_crtc->randr_crtc; +} + + +/* + * Initialize xf86CrtcConfig structure + */ + +extern _X_EXPORT void +xf86CrtcConfigInit (ScrnInfoPtr scrn, + const xf86CrtcConfigFuncsRec *funcs); + +extern _X_EXPORT void +xf86CrtcSetSizeRange (ScrnInfoPtr scrn, + int minWidth, int minHeight, + int maxWidth, int maxHeight); + +/* + * Crtc functions + */ +extern _X_EXPORT xf86CrtcPtr +xf86CrtcCreate (ScrnInfoPtr scrn, + const xf86CrtcFuncsRec *funcs); + +extern _X_EXPORT void +xf86CrtcDestroy (xf86CrtcPtr crtc); + + +/** + * Sets the given video mode on the given crtc + */ + +extern _X_EXPORT Bool +xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + RRTransformPtr transform, int x, int y); + +extern _X_EXPORT Bool +xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y); + +extern _X_EXPORT void +xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y); + +/* + * Assign crtc rotation during mode set + */ +extern _X_EXPORT Bool +xf86CrtcRotate (xf86CrtcPtr crtc); + +/* + * Clean up any rotation data, used when a crtc is turned off + * as well as when rotation is disabled. + */ +extern _X_EXPORT void +xf86RotateDestroy (xf86CrtcPtr crtc); + +/* + * free shadow memory allocated for all crtcs + */ +extern _X_EXPORT void +xf86RotateFreeShadow(ScrnInfoPtr pScrn); + +/* + * Clean up rotation during CloseScreen + */ +extern _X_EXPORT void +xf86RotateCloseScreen (ScreenPtr pScreen); + +/** + * Return whether any output is assigned to the crtc + */ +extern _X_EXPORT Bool +xf86CrtcInUse (xf86CrtcPtr crtc); + +/* + * Output functions + */ +extern _X_EXPORT xf86OutputPtr +xf86OutputCreate (ScrnInfoPtr scrn, + const xf86OutputFuncsRec *funcs, + const char *name); + +extern _X_EXPORT void +xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor); + +extern _X_EXPORT Bool +xf86OutputRename (xf86OutputPtr output, const char *name); + +extern _X_EXPORT void +xf86OutputDestroy (xf86OutputPtr output); + +extern _X_EXPORT void +xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY); + +extern _X_EXPORT void +xf86SetScrnInfoModes (ScrnInfoPtr pScrn); + +#ifdef RANDR_13_INTERFACE +# define ScreenInitRetType int +#else +# define ScreenInitRetType Bool +#endif + +extern _X_EXPORT ScreenInitRetType +xf86CrtcScreenInit (ScreenPtr pScreen); + +extern _X_EXPORT Bool +xf86InitialConfiguration (ScrnInfoPtr pScrn, Bool canGrow); + +extern _X_EXPORT void +xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); + +extern _X_EXPORT Bool +xf86SaveScreen(ScreenPtr pScreen, int mode); + +extern _X_EXPORT void +xf86DisableUnusedFunctions(ScrnInfoPtr pScrn); + +extern _X_EXPORT DisplayModePtr +xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired); + +extern _X_EXPORT Bool +xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation); + +/** + * Set the EDID information for the specified output + */ +extern _X_EXPORT void +xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon); + +/** + * Return the list of modes supported by the EDID information + * stored in 'output' + */ +extern _X_EXPORT DisplayModePtr +xf86OutputGetEDIDModes (xf86OutputPtr output); + +extern _X_EXPORT xf86MonPtr +xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus); + +/** + * Initialize dga for this screen + */ + +#ifdef XFreeXDGA +extern _X_EXPORT Bool +xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address); + +/* this is the real function, used only internally */ +_X_INTERNAL Bool +_xf86_di_dga_init_internal (ScreenPtr pScreen); + +/** + * Re-initialize dga for this screen (as when the set of modes changes) + */ + +extern _X_EXPORT Bool +xf86DiDGAReInit (ScreenPtr pScreen); +#endif + +/* This is the real function, used only internally */ +_X_INTERNAL Bool +_xf86_di_dga_reinit_internal (ScreenPtr pScreen); + +/* + * Set the subpixel order reported for the screen using + * the information from the outputs + */ + +extern _X_EXPORT void +xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen); + +/* + * Get a standard string name for a connector type + */ +extern _X_EXPORT char * +xf86ConnectorGetName(xf86ConnectorType connector); + +/* + * Using the desired mode information in each crtc, set + * modes (used in EnterVT functions, or at server startup) + */ + +extern _X_EXPORT Bool +xf86SetDesiredModes (ScrnInfoPtr pScrn); + +/** + * Initialize the CRTC-based cursor code. CRTC function vectors must + * contain relevant cursor setting functions. + * + * Driver should call this from ScreenInit function + */ +extern _X_EXPORT Bool +xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags); + +/** + * Called when anything on the screen is reconfigured. + * + * Reloads cursor images as needed, then adjusts cursor positions. + * + * Driver should call this from crtc commit function. + */ +extern _X_EXPORT void +xf86_reload_cursors (ScreenPtr screen); + +/** + * Called from EnterVT to turn the cursors back on + */ +extern _X_EXPORT void +xf86_show_cursors (ScrnInfoPtr scrn); + +/** + * Called by the driver to turn cursors off + */ +extern _X_EXPORT void +xf86_hide_cursors (ScrnInfoPtr scrn); + +/** + * Clean up CRTC-based cursor code. Driver must call this at CloseScreen time. + */ +extern _X_EXPORT void +xf86_cursors_fini (ScreenPtr screen); + +/* + * For overlay video, compute the relevant CRTC and + * clip video to that. + * wraps xf86XVClipVideoHelper() + */ + +extern _X_EXPORT Bool +xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn, + xf86CrtcPtr *crtc_ret, + xf86CrtcPtr desired_crtc, + BoxPtr dst, + INT32 *xa, + INT32 *xb, + INT32 *ya, + INT32 *yb, + RegionPtr reg, + INT32 width, + INT32 height); + +extern _X_EXPORT xf86_crtc_notify_proc_ptr +xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new); + +extern _X_EXPORT void +xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old); + +extern _X_EXPORT void +xf86_crtc_notify(ScreenPtr pScreen); + +/** + * Gamma + */ + +extern _X_EXPORT Bool +xf86_crtc_supports_gamma(ScrnInfoPtr pScrn); + +#endif /* _XF86CRTC_H_ */ diff --git a/xorg-server/hw/xfree86/modes/xf86Cursors.c b/xorg-server/hw/xfree86/modes/xf86Cursors.c index 3c2958743..066744744 100644 --- a/xorg-server/hw/xfree86/modes/xf86Cursors.c +++ b/xorg-server/hw/xfree86/modes/xf86Cursors.c @@ -1,688 +1,688 @@ -/* - * Copyright © 2007 Keith Packard - * Copyright © 2010 Aaron Plattner - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#else -#ifdef HAVE_CONFIG_H -#include -#endif -#endif - -#include -#include -#include - -#include "xf86.h" -#include "xf86DDC.h" -#include "xf86Crtc.h" -#include "xf86Modes.h" -#include "xf86RandR12.h" -#include "xf86CursorPriv.h" -#include "X11/extensions/render.h" -#include "X11/extensions/dpmsconst.h" -#include "X11/Xatom.h" -#include "picturestr.h" -#include "cursorstr.h" -#include "inputstr.h" - -/* - * Given a screen coordinate, rotate back to a cursor source coordinate - */ -static void -xf86_crtc_rotate_coord (Rotation rotation, - int width, - int height, - int x_dst, - int y_dst, - int *x_src, - int *y_src) -{ - int t; - - switch (rotation & 0xf) { - case RR_Rotate_0: - break; - case RR_Rotate_90: - t = x_dst; - x_dst = height - y_dst - 1; - y_dst = t; - break; - case RR_Rotate_180: - x_dst = width - x_dst - 1; - y_dst = height - y_dst - 1; - break; - case RR_Rotate_270: - t = x_dst; - x_dst = y_dst; - y_dst = width - t - 1; - break; - } - if (rotation & RR_Reflect_X) - x_dst = width - x_dst - 1; - if (rotation & RR_Reflect_Y) - y_dst = height - y_dst - 1; - *x_src = x_dst; - *y_src = y_dst; -} - -/* - * Given a cursor source coordinate, rotate to a screen coordinate - */ -static void -xf86_crtc_rotate_coord_back (Rotation rotation, - int width, - int height, - int x_dst, - int y_dst, - int *x_src, - int *y_src) -{ - int t; - - if (rotation & RR_Reflect_X) - x_dst = width - x_dst - 1; - if (rotation & RR_Reflect_Y) - y_dst = height - y_dst - 1; - - switch (rotation & 0xf) { - case RR_Rotate_0: - break; - case RR_Rotate_90: - t = x_dst; - x_dst = y_dst; - y_dst = width - t - 1; - break; - case RR_Rotate_180: - x_dst = width - x_dst - 1; - y_dst = height - y_dst - 1; - break; - case RR_Rotate_270: - t = x_dst; - x_dst = height - y_dst - 1; - y_dst = t; - break; - } - *x_src = x_dst; - *y_src = y_dst; -} - -struct cursor_bit { - CARD8 *byte; - char bitpos; -}; - -/* - * Convert an x coordinate to a position within the cursor bitmap - */ -static struct cursor_bit -cursor_bitpos (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, - Bool mask) -{ - const int flags = cursor_info->Flags; - const Bool interleaved = - !!(flags & (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)); - const int width = cursor_info->MaxWidth; - const int height = cursor_info->MaxHeight; - const int stride = interleaved ? width / 4 : width / 8; - - struct cursor_bit ret; - - image += y * stride; - - if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) - mask = !mask; - if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) - x = (x & ~3) | (3 - (x & 3)); - if (((flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) == 0) == - (X_BYTE_ORDER == X_BIG_ENDIAN)) - x = (x & ~7) | (7 - (x & 7)); - if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1) - x = (x << 1) + mask; - else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8) - x = ((x & ~7) << 1) | (mask << 3) | (x & 7); - else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16) - x = ((x & ~15) << 1) | (mask << 4) | (x & 15); - else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32) - x = ((x & ~31) << 1) | (mask << 5) | (x & 31); - else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64) - x = ((x & ~63) << 1) | (mask << 6) | (x & 63); - else if (mask) - image += stride * height; - - ret.byte = image + (x / 8); - ret.bitpos = x & 7; - - return ret; -} - -/* - * Fetch one bit from a cursor bitmap - */ -static CARD8 -get_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask) -{ - struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask); - return (*bit.byte >> bit.bitpos) & 1; -} - -/* - * Set one bit in a cursor bitmap - */ -static void -set_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask) -{ - struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask); - *bit.byte |= 1 << bit.bitpos; -} - -/* - * Load a two color cursor into a driver that supports only ARGB cursors - */ -static void -xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src) -{ - ScrnInfoPtr scrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image; - int x, y; - int xin, yin; - int flags = cursor_info->Flags; - CARD32 bits; - -#ifdef ARGB_CURSOR - crtc->cursor_argb = FALSE; -#endif - - for (y = 0; y < cursor_info->MaxHeight; y++) - for (x = 0; x < cursor_info->MaxWidth; x++) - { - xf86_crtc_rotate_coord (crtc->rotation, - cursor_info->MaxWidth, - cursor_info->MaxHeight, - x, y, &xin, &yin); - if (get_bit (src, cursor_info, xin, yin, TRUE) == - ((flags & HARDWARE_CURSOR_INVERT_MASK) == 0)) - { - if (get_bit (src, cursor_info, xin, yin, FALSE)) - bits = xf86_config->cursor_fg; - else - bits = xf86_config->cursor_bg; - } - else - bits = 0; - cursor_image[y * cursor_info->MaxWidth + x] = bits; - } - crtc->funcs->load_cursor_argb (crtc, cursor_image); -} - -/* - * Set the colors for a two-color cursor (ignore for ARGB cursors) - */ -static void -xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg) -{ - ScreenPtr screen = scrn->pScreen; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - CursorPtr cursor = xf86_config->cursor; - int c; - CARD8 *bits = cursor ? - dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen)) - : NULL; - - /* Save ARGB versions of these colors */ - xf86_config->cursor_fg = (CARD32) fg | 0xff000000; - xf86_config->cursor_bg = (CARD32) bg | 0xff000000; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->enabled && !crtc->cursor_argb) - { - if (crtc->funcs->load_cursor_image) - crtc->funcs->set_cursor_colors (crtc, bg, fg); - else if (bits) - xf86_crtc_convert_cursor_to_argb (crtc, bits); - } - } -} - -static void -xf86_crtc_hide_cursor (xf86CrtcPtr crtc) -{ - if (crtc->cursor_shown) - { - crtc->funcs->hide_cursor (crtc); - crtc->cursor_shown = FALSE; - } -} - -void -xf86_hide_cursors (ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - xf86_config->cursor_on = FALSE; - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->enabled) - xf86_crtc_hide_cursor (crtc); - } -} - -static void -xf86_crtc_show_cursor (xf86CrtcPtr crtc) -{ - if (!crtc->cursor_shown && crtc->cursor_in_range) - { - crtc->funcs->show_cursor (crtc); - crtc->cursor_shown = TRUE; - } -} - -void -xf86_show_cursors (ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - xf86_config->cursor_on = TRUE; - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->enabled) - xf86_crtc_show_cursor (crtc); - } -} - -static void -xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) -{ - ScrnInfoPtr scrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - DisplayModePtr mode = &crtc->mode; - Bool in_range; - int dx, dy; - - /* - * Transform position of cursor on screen - */ - if (crtc->sprite_transform_in_use) - { - ScreenPtr screen = scrn->pScreen; - xf86CursorScreenPtr ScreenPriv = - (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates, - xf86CursorScreenKey); - struct pict_f_vector v; - - v.v[0] = (x + ScreenPriv->HotX) + 0.5; - v.v[1] = (y + ScreenPriv->HotY) + 0.5; - v.v[2] = 1; - pixman_f_transform_point (&crtc->f_screen_to_crtc, &v); - /* cursor will have 0.5 added to it already so floor is sufficent */ - x = floor (v.v[0]); - y = floor (v.v[1]); - /* - * Transform position of cursor upper left corner - */ - xf86_crtc_rotate_coord_back (crtc->rotation, - cursor_info->MaxWidth, - cursor_info->MaxHeight, - ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy); - x -= dx; - y -= dy; - } - else - { - x -= crtc->x; - y -= crtc->y; - } - - /* - * Disable the cursor when it is outside the viewport - */ - in_range = TRUE; - if (x >= mode->HDisplay || y >= mode->VDisplay || - x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight) - { - in_range = FALSE; - x = 0; - y = 0; - } - - crtc->cursor_in_range = in_range; - - if (in_range) - { - crtc->funcs->set_cursor_position (crtc, x, y); - xf86_crtc_show_cursor (crtc); - } - else - xf86_crtc_hide_cursor (crtc); -} - -static void -xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - /* undo what xf86HWCurs did to the coordinates */ - x += scrn->frameX0; - y += scrn->frameY0; - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->enabled) - xf86_crtc_set_cursor_position (crtc, x, y); - } -} - -/* - * Load a two-color cursor into a crtc, performing rotation as needed - */ -static void -xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src) -{ - ScrnInfoPtr scrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - CARD8 *cursor_image; - -#ifdef ARGB_CURSOR - crtc->cursor_argb = FALSE; -#endif - - if (crtc->rotation == RR_Rotate_0) - cursor_image = src; - else - { - int x, y; - int xin, yin; - int stride = cursor_info->MaxWidth >> 2; - - cursor_image = xf86_config->cursor_image; - memset(cursor_image, 0, cursor_info->MaxHeight * stride); - - for (y = 0; y < cursor_info->MaxHeight; y++) - for (x = 0; x < cursor_info->MaxWidth; x++) - { - xf86_crtc_rotate_coord (crtc->rotation, - cursor_info->MaxWidth, - cursor_info->MaxHeight, - x, y, &xin, &yin); - if (get_bit(src, cursor_info, xin, yin, FALSE)) - set_bit(cursor_image, cursor_info, x, y, FALSE); - if (get_bit(src, cursor_info, xin, yin, TRUE)) - set_bit(cursor_image, cursor_info, x, y, TRUE); - } - } - crtc->funcs->load_cursor_image (crtc, cursor_image); -} - -/* - * Load a cursor image into all active CRTCs - */ -static void -xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->enabled) - { - if (crtc->funcs->load_cursor_image) - xf86_crtc_load_cursor_image (crtc, src); - else if (crtc->funcs->load_cursor_argb) - xf86_crtc_convert_cursor_to_argb (crtc, src); - } - } -} - -static Bool -xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - - ++cursor->refcnt; - if (xf86_config->cursor) - FreeCursor (xf86_config->cursor, None); - xf86_config->cursor = cursor; - - if (cursor->bits->width > cursor_info->MaxWidth || - cursor->bits->height> cursor_info->MaxHeight) - return FALSE; - - return TRUE; -} - -static Bool -xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - - ++cursor->refcnt; - if (xf86_config->cursor) - FreeCursor (xf86_config->cursor, None); - xf86_config->cursor = cursor; - - /* Make sure ARGB support is available */ - if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0) - return FALSE; - - if (cursor->bits->width > cursor_info->MaxWidth || - cursor->bits->height> cursor_info->MaxHeight) - return FALSE; - - return TRUE; -} - -static void -xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor) -{ - ScrnInfoPtr scrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image; - CARD32 *cursor_source = (CARD32 *) cursor->bits->argb; - int x, y; - int xin, yin; - CARD32 bits; - int source_width = cursor->bits->width; - int source_height = cursor->bits->height; - int image_width = cursor_info->MaxWidth; - int image_height = cursor_info->MaxHeight; - - for (y = 0; y < image_height; y++) - for (x = 0; x < image_width; x++) - { - xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height, - x, y, &xin, &yin); - if (xin < source_width && yin < source_height) - bits = cursor_source[yin * source_width + xin]; - else - bits = 0; - cursor_image[y * image_width + x] = bits; - } - - crtc->funcs->load_cursor_argb (crtc, cursor_image); -} - -static void -xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->enabled) - xf86_crtc_load_cursor_argb (crtc, cursor); - } -} - -Bool -xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CursorInfoPtr cursor_info; - - cursor_info = xf86CreateCursorInfoRec(); - if (!cursor_info) - return FALSE; - - xf86_config->cursor_image = malloc(max_width * max_height * 4); - - if (!xf86_config->cursor_image) - { - xf86DestroyCursorInfoRec (cursor_info); - return FALSE; - } - - xf86_config->cursor_info = cursor_info; - - cursor_info->MaxWidth = max_width; - cursor_info->MaxHeight = max_height; - cursor_info->Flags = flags; - - cursor_info->SetCursorColors = xf86_set_cursor_colors; - cursor_info->SetCursorPosition = xf86_set_cursor_position; - cursor_info->LoadCursorImage = xf86_load_cursor_image; - cursor_info->HideCursor = xf86_hide_cursors; - cursor_info->ShowCursor = xf86_show_cursors; - cursor_info->UseHWCursor = xf86_use_hw_cursor; -#ifdef ARGB_CURSOR - if (flags & HARDWARE_CURSOR_ARGB) - { - cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb; - cursor_info->LoadCursorARGB = xf86_load_cursor_argb; - } -#endif - - xf86_config->cursor = NULL; - xf86_hide_cursors (scrn); - - return xf86InitCursor (screen, cursor_info); -} - -/** - * Called when anything on the screen is reconfigured. - * - * Reloads cursor images as needed, then adjusts cursor positions - */ - -void -xf86_reload_cursors (ScreenPtr screen) -{ - ScrnInfoPtr scrn; - xf86CrtcConfigPtr xf86_config; - xf86CursorInfoPtr cursor_info; - CursorPtr cursor; - int x, y; - xf86CursorScreenPtr cursor_screen_priv; - - /* initial mode setting will not have set a screen yet. - May be called before the devices are initialised. - */ - if (!screen || !inputInfo.pointer) - return; - cursor_screen_priv = dixLookupPrivate(&screen->devPrivates, - xf86CursorScreenKey); - /* return if HW cursor is inactive, to avoid displaying two cursors */ - if (!cursor_screen_priv || !cursor_screen_priv->isUp) - return; - - scrn = xf86Screens[screen->myNum]; - xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - - /* make sure the cursor code has been initialized */ - cursor_info = xf86_config->cursor_info; - if (!cursor_info) - return; - - cursor = xf86_config->cursor; - GetSpritePosition (inputInfo.pointer, &x, &y); - if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) - (*cursor_info->HideCursor)(scrn); - - if (cursor) - { - void *src = dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen)); -#ifdef ARGB_CURSOR - if (cursor->bits->argb && cursor_info->LoadCursorARGB) - (*cursor_info->LoadCursorARGB) (scrn, cursor); - else if (src) -#endif - (*cursor_info->LoadCursorImage)(scrn, src); - - x += scrn->frameX0 + cursor_screen_priv->HotX; - y += scrn->frameY0 + cursor_screen_priv->HotY; - (*cursor_info->SetCursorPosition)(scrn, x, y); - } -} - -/** - * Clean up CRTC-based cursor code - */ -void -xf86_cursors_fini (ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - - if (xf86_config->cursor_info) - { - xf86DestroyCursorInfoRec (xf86_config->cursor_info); - xf86_config->cursor_info = NULL; - } - free(xf86_config->cursor_image); - xf86_config->cursor_image = NULL; - if (xf86_config->cursor) - { - FreeCursor (xf86_config->cursor, None); - xf86_config->cursor = NULL; - } -} +/* + * Copyright © 2007 Keith Packard + * Copyright © 2010 Aaron Plattner + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#else +#ifdef HAVE_CONFIG_H +#include +#endif +#endif + +#include +#include +#include + +#include "xf86.h" +#include "xf86DDC.h" +#include "xf86Crtc.h" +#include "xf86Modes.h" +#include "xf86RandR12.h" +#include "xf86CursorPriv.h" +#include "X11/extensions/render.h" +#include "X11/extensions/dpmsconst.h" +#include "X11/Xatom.h" +#include "picturestr.h" +#include "cursorstr.h" +#include "inputstr.h" + +/* + * Given a screen coordinate, rotate back to a cursor source coordinate + */ +static void +xf86_crtc_rotate_coord (Rotation rotation, + int width, + int height, + int x_dst, + int y_dst, + int *x_src, + int *y_src) +{ + int t; + + switch (rotation & 0xf) { + case RR_Rotate_0: + break; + case RR_Rotate_90: + t = x_dst; + x_dst = height - y_dst - 1; + y_dst = t; + break; + case RR_Rotate_180: + x_dst = width - x_dst - 1; + y_dst = height - y_dst - 1; + break; + case RR_Rotate_270: + t = x_dst; + x_dst = y_dst; + y_dst = width - t - 1; + break; + } + if (rotation & RR_Reflect_X) + x_dst = width - x_dst - 1; + if (rotation & RR_Reflect_Y) + y_dst = height - y_dst - 1; + *x_src = x_dst; + *y_src = y_dst; +} + +/* + * Given a cursor source coordinate, rotate to a screen coordinate + */ +static void +xf86_crtc_rotate_coord_back (Rotation rotation, + int width, + int height, + int x_dst, + int y_dst, + int *x_src, + int *y_src) +{ + int t; + + if (rotation & RR_Reflect_X) + x_dst = width - x_dst - 1; + if (rotation & RR_Reflect_Y) + y_dst = height - y_dst - 1; + + switch (rotation & 0xf) { + case RR_Rotate_0: + break; + case RR_Rotate_90: + t = x_dst; + x_dst = y_dst; + y_dst = width - t - 1; + break; + case RR_Rotate_180: + x_dst = width - x_dst - 1; + y_dst = height - y_dst - 1; + break; + case RR_Rotate_270: + t = x_dst; + x_dst = height - y_dst - 1; + y_dst = t; + break; + } + *x_src = x_dst; + *y_src = y_dst; +} + +struct cursor_bit { + CARD8 *byte; + char bitpos; +}; + +/* + * Convert an x coordinate to a position within the cursor bitmap + */ +static struct cursor_bit +cursor_bitpos (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, + Bool mask) +{ + const int flags = cursor_info->Flags; + const Bool interleaved = + !!(flags & (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)); + const int width = cursor_info->MaxWidth; + const int height = cursor_info->MaxHeight; + const int stride = interleaved ? width / 4 : width / 8; + + struct cursor_bit ret; + + image += y * stride; + + if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) + mask = !mask; + if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) + x = (x & ~3) | (3 - (x & 3)); + if (((flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) == 0) == + (X_BYTE_ORDER == X_BIG_ENDIAN)) + x = (x & ~7) | (7 - (x & 7)); + if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1) + x = (x << 1) + mask; + else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8) + x = ((x & ~7) << 1) | (mask << 3) | (x & 7); + else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16) + x = ((x & ~15) << 1) | (mask << 4) | (x & 15); + else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32) + x = ((x & ~31) << 1) | (mask << 5) | (x & 31); + else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64) + x = ((x & ~63) << 1) | (mask << 6) | (x & 63); + else if (mask) + image += stride * height; + + ret.byte = image + (x / 8); + ret.bitpos = x & 7; + + return ret; +} + +/* + * Fetch one bit from a cursor bitmap + */ +static CARD8 +get_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask) +{ + struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask); + return (*bit.byte >> bit.bitpos) & 1; +} + +/* + * Set one bit in a cursor bitmap + */ +static void +set_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask) +{ + struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask); + *bit.byte |= 1 << bit.bitpos; +} + +/* + * Load a two color cursor into a driver that supports only ARGB cursors + */ +static void +xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image; + int x, y; + int xin, yin; + int flags = cursor_info->Flags; + CARD32 bits; + +#ifdef ARGB_CURSOR + crtc->cursor_argb = FALSE; +#endif + + for (y = 0; y < cursor_info->MaxHeight; y++) + for (x = 0; x < cursor_info->MaxWidth; x++) + { + xf86_crtc_rotate_coord (crtc->rotation, + cursor_info->MaxWidth, + cursor_info->MaxHeight, + x, y, &xin, &yin); + if (get_bit (src, cursor_info, xin, yin, TRUE) == + ((flags & HARDWARE_CURSOR_INVERT_MASK) == 0)) + { + if (get_bit (src, cursor_info, xin, yin, FALSE)) + bits = xf86_config->cursor_fg; + else + bits = xf86_config->cursor_bg; + } + else + bits = 0; + cursor_image[y * cursor_info->MaxWidth + x] = bits; + } + crtc->funcs->load_cursor_argb (crtc, cursor_image); +} + +/* + * Set the colors for a two-color cursor (ignore for ARGB cursors) + */ +static void +xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg) +{ + ScreenPtr screen = scrn->pScreen; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + CursorPtr cursor = xf86_config->cursor; + int c; + CARD8 *bits = cursor ? + dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen)) + : NULL; + + /* Save ARGB versions of these colors */ + xf86_config->cursor_fg = (CARD32) fg | 0xff000000; + xf86_config->cursor_bg = (CARD32) bg | 0xff000000; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->enabled && !crtc->cursor_argb) + { + if (crtc->funcs->load_cursor_image) + crtc->funcs->set_cursor_colors (crtc, bg, fg); + else if (bits) + xf86_crtc_convert_cursor_to_argb (crtc, bits); + } + } +} + +static void +xf86_crtc_hide_cursor (xf86CrtcPtr crtc) +{ + if (crtc->cursor_shown) + { + crtc->funcs->hide_cursor (crtc); + crtc->cursor_shown = FALSE; + } +} + +void +xf86_hide_cursors (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + xf86_config->cursor_on = FALSE; + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->enabled) + xf86_crtc_hide_cursor (crtc); + } +} + +static void +xf86_crtc_show_cursor (xf86CrtcPtr crtc) +{ + if (!crtc->cursor_shown && crtc->cursor_in_range) + { + crtc->funcs->show_cursor (crtc); + crtc->cursor_shown = TRUE; + } +} + +void +xf86_show_cursors (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + xf86_config->cursor_on = TRUE; + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->enabled) + xf86_crtc_show_cursor (crtc); + } +} + +static void +xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + DisplayModePtr mode = &crtc->mode; + Bool in_range; + int dx, dy; + + /* + * Transform position of cursor on screen + */ + if (crtc->transform_in_use) + { + ScreenPtr screen = scrn->pScreen; + xf86CursorScreenPtr ScreenPriv = + (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates, + xf86CursorScreenKey); + struct pict_f_vector v; + + v.v[0] = (x + ScreenPriv->HotX) + 0.5; + v.v[1] = (y + ScreenPriv->HotY) + 0.5; + v.v[2] = 1; + pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v); + /* cursor will have 0.5 added to it already so floor is sufficent */ + x = floor (v.v[0]); + y = floor (v.v[1]); + /* + * Transform position of cursor upper left corner + */ + xf86_crtc_rotate_coord_back (crtc->rotation, + cursor_info->MaxWidth, + cursor_info->MaxHeight, + ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy); + x -= dx; + y -= dy; + } + else + { + x -= crtc->x; + y -= crtc->y; + } + + /* + * Disable the cursor when it is outside the viewport + */ + in_range = TRUE; + if (x >= mode->HDisplay || y >= mode->VDisplay || + x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight) + { + in_range = FALSE; + x = 0; + y = 0; + } + + crtc->cursor_in_range = in_range; + + if (in_range) + { + crtc->funcs->set_cursor_position (crtc, x, y); + xf86_crtc_show_cursor (crtc); + } + else + xf86_crtc_hide_cursor (crtc); +} + +static void +xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + /* undo what xf86HWCurs did to the coordinates */ + x += scrn->frameX0; + y += scrn->frameY0; + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->enabled) + xf86_crtc_set_cursor_position (crtc, x, y); + } +} + +/* + * Load a two-color cursor into a crtc, performing rotation as needed + */ +static void +xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + CARD8 *cursor_image; + +#ifdef ARGB_CURSOR + crtc->cursor_argb = FALSE; +#endif + + if (crtc->rotation == RR_Rotate_0) + cursor_image = src; + else + { + int x, y; + int xin, yin; + int stride = cursor_info->MaxWidth >> 2; + + cursor_image = xf86_config->cursor_image; + memset(cursor_image, 0, cursor_info->MaxHeight * stride); + + for (y = 0; y < cursor_info->MaxHeight; y++) + for (x = 0; x < cursor_info->MaxWidth; x++) + { + xf86_crtc_rotate_coord (crtc->rotation, + cursor_info->MaxWidth, + cursor_info->MaxHeight, + x, y, &xin, &yin); + if (get_bit(src, cursor_info, xin, yin, FALSE)) + set_bit(cursor_image, cursor_info, x, y, FALSE); + if (get_bit(src, cursor_info, xin, yin, TRUE)) + set_bit(cursor_image, cursor_info, x, y, TRUE); + } + } + crtc->funcs->load_cursor_image (crtc, cursor_image); +} + +/* + * Load a cursor image into all active CRTCs + */ +static void +xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->enabled) + { + if (crtc->funcs->load_cursor_image) + xf86_crtc_load_cursor_image (crtc, src); + else if (crtc->funcs->load_cursor_argb) + xf86_crtc_convert_cursor_to_argb (crtc, src); + } + } +} + +static Bool +xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + + ++cursor->refcnt; + if (xf86_config->cursor) + FreeCursor (xf86_config->cursor, None); + xf86_config->cursor = cursor; + + if (cursor->bits->width > cursor_info->MaxWidth || + cursor->bits->height> cursor_info->MaxHeight) + return FALSE; + + return TRUE; +} + +static Bool +xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + + ++cursor->refcnt; + if (xf86_config->cursor) + FreeCursor (xf86_config->cursor, None); + xf86_config->cursor = cursor; + + /* Make sure ARGB support is available */ + if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0) + return FALSE; + + if (cursor->bits->width > cursor_info->MaxWidth || + cursor->bits->height> cursor_info->MaxHeight) + return FALSE; + + return TRUE; +} + +static void +xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image; + CARD32 *cursor_source = (CARD32 *) cursor->bits->argb; + int x, y; + int xin, yin; + CARD32 bits; + int source_width = cursor->bits->width; + int source_height = cursor->bits->height; + int image_width = cursor_info->MaxWidth; + int image_height = cursor_info->MaxHeight; + + for (y = 0; y < image_height; y++) + for (x = 0; x < image_width; x++) + { + xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height, + x, y, &xin, &yin); + if (xin < source_width && yin < source_height) + bits = cursor_source[yin * source_width + xin]; + else + bits = 0; + cursor_image[y * image_width + x] = bits; + } + + crtc->funcs->load_cursor_argb (crtc, cursor_image); +} + +static void +xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->enabled) + xf86_crtc_load_cursor_argb (crtc, cursor); + } +} + +Bool +xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info; + + cursor_info = xf86CreateCursorInfoRec(); + if (!cursor_info) + return FALSE; + + xf86_config->cursor_image = malloc(max_width * max_height * 4); + + if (!xf86_config->cursor_image) + { + xf86DestroyCursorInfoRec (cursor_info); + return FALSE; + } + + xf86_config->cursor_info = cursor_info; + + cursor_info->MaxWidth = max_width; + cursor_info->MaxHeight = max_height; + cursor_info->Flags = flags; + + cursor_info->SetCursorColors = xf86_set_cursor_colors; + cursor_info->SetCursorPosition = xf86_set_cursor_position; + cursor_info->LoadCursorImage = xf86_load_cursor_image; + cursor_info->HideCursor = xf86_hide_cursors; + cursor_info->ShowCursor = xf86_show_cursors; + cursor_info->UseHWCursor = xf86_use_hw_cursor; +#ifdef ARGB_CURSOR + if (flags & HARDWARE_CURSOR_ARGB) + { + cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb; + cursor_info->LoadCursorARGB = xf86_load_cursor_argb; + } +#endif + + xf86_config->cursor = NULL; + xf86_hide_cursors (scrn); + + return xf86InitCursor (screen, cursor_info); +} + +/** + * Called when anything on the screen is reconfigured. + * + * Reloads cursor images as needed, then adjusts cursor positions + */ + +void +xf86_reload_cursors (ScreenPtr screen) +{ + ScrnInfoPtr scrn; + xf86CrtcConfigPtr xf86_config; + xf86CursorInfoPtr cursor_info; + CursorPtr cursor; + int x, y; + xf86CursorScreenPtr cursor_screen_priv; + + /* initial mode setting will not have set a screen yet. + May be called before the devices are initialised. + */ + if (!screen || !inputInfo.pointer) + return; + cursor_screen_priv = dixLookupPrivate(&screen->devPrivates, + xf86CursorScreenKey); + /* return if HW cursor is inactive, to avoid displaying two cursors */ + if (!cursor_screen_priv || !cursor_screen_priv->isUp) + return; + + scrn = xf86Screens[screen->myNum]; + xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + + /* make sure the cursor code has been initialized */ + cursor_info = xf86_config->cursor_info; + if (!cursor_info) + return; + + cursor = xf86_config->cursor; + GetSpritePosition (inputInfo.pointer, &x, &y); + if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) + (*cursor_info->HideCursor)(scrn); + + if (cursor) + { + void *src = dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen)); +#ifdef ARGB_CURSOR + if (cursor->bits->argb && cursor_info->LoadCursorARGB) + (*cursor_info->LoadCursorARGB) (scrn, cursor); + else if (src) +#endif + (*cursor_info->LoadCursorImage)(scrn, src); + + x += scrn->frameX0 + cursor_screen_priv->HotX; + y += scrn->frameY0 + cursor_screen_priv->HotY; + (*cursor_info->SetCursorPosition)(scrn, x, y); + } +} + +/** + * Clean up CRTC-based cursor code + */ +void +xf86_cursors_fini (ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + + if (xf86_config->cursor_info) + { + xf86DestroyCursorInfoRec (xf86_config->cursor_info); + xf86_config->cursor_info = NULL; + } + free(xf86_config->cursor_image); + xf86_config->cursor_image = NULL; + if (xf86_config->cursor) + { + FreeCursor (xf86_config->cursor, None); + xf86_config->cursor = NULL; + } +} diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c index 7bfb6fa47..2fe0c47e6 100644 --- a/xorg-server/hw/xfree86/modes/xf86RandR12.c +++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c @@ -1,2029 +1,1802 @@ -/* - * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#else -#ifdef HAVE_CONFIG_H -#include -#endif -#endif - -#include "xf86.h" -#include "os.h" -#include "globals.h" -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86DDC.h" -#include "mipointer.h" -#include "windowstr.h" -#include "inputstr.h" -#include -#include - -#include "xf86Crtc.h" -#include "xf86RandR12.h" - -typedef struct _xf86RandR12Info { - int virtualX; - int virtualY; - int mmWidth; - int mmHeight; - int maxX; - int maxY; - int pointerX; - int pointerY; - Rotation rotation; /* current mode */ - Rotation supported_rotations; /* driver supported */ - - /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends - * (actually, any time that we switch back into our VT). - * - * See https://bugs.freedesktop.org/show_bug.cgi?id=21554 - */ - xf86EnterVTProc *orig_EnterVT; -} XF86RandRInfoRec, *XF86RandRInfoPtr; - -#ifdef RANDR_12_INTERFACE -static Bool xf86RandR12Init12 (ScreenPtr pScreen); -static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen); -#endif - -static int xf86RandR12Generation; - -static DevPrivateKeyRec xf86RandR12KeyRec; -static DevPrivateKey xf86RandR12Key; -#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ - dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key)) - - -static int -xf86RandR12ModeRefresh (DisplayModePtr mode) -{ - if (mode->VRefresh) - return (int) (mode->VRefresh + 0.5); - else - return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5); -} - -/* Adapt panning area; return TRUE if panning area was valid without adaption */ -static int -xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight) -{ - int ret = TRUE; - - if (crtc->version < 2) - return FALSE; - - if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) { - /* Panning in X is disabled */ - if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2) - /* Illegal configuration -> fail/disable */ - ret = FALSE; - crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0; - crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0; - crtc->panningBorder[0] = crtc->panningBorder[2] = 0; - } else { - /* Panning in X is enabled */ - if (crtc->panningTotalArea.x1 < 0) { - /* Panning region outside screen -> move inside */ - crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1; - crtc->panningTotalArea.x1 = 0; - ret = FALSE; - } - if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) { - /* Panning region smaller than displayed area -> crop to displayed area */ - crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay; - ret = FALSE; - } - if (crtc->panningTotalArea.x2 > screenWidth) { - /* Panning region larger than screen -> move inside, then crop to screen */ - crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth; - crtc->panningTotalArea.x2 = screenWidth; - ret = FALSE; - if (crtc->panningTotalArea.x1 < 0) - crtc->panningTotalArea.x1 = 0; - } - if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) { - /* Borders too large -> set to 0 */ - crtc->panningBorder[0] = crtc->panningBorder[2] = 0; - ret = FALSE; - } - } - - if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) { - /* Panning in Y is disabled */ - if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2) - /* Illegal configuration -> fail/disable */ - ret = FALSE; - crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0; - crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0; - crtc->panningBorder[1] = crtc->panningBorder[3] = 0; - } else { - /* Panning in Y is enabled */ - if (crtc->panningTotalArea.y1 < 0) { - /* Panning region outside screen -> move inside */ - crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1; - crtc->panningTotalArea.y1 = 0; - ret = FALSE; - } - if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) { - /* Panning region smaller than displayed area -> crop to displayed area */ - crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay; - ret = FALSE; - } - if (crtc->panningTotalArea.y2 > screenHeight) { - /* Panning region larger than screen -> move inside, then crop to screen */ - crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight; - crtc->panningTotalArea.y2 = screenHeight; - ret = FALSE; - if (crtc->panningTotalArea.y1 < 0) - crtc->panningTotalArea.y1 = 0; - } - if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) { - /* Borders too large -> set to 0 */ - crtc->panningBorder[1] = crtc->panningBorder[3] = 0; - ret = FALSE; - } - } - - return ret; -} - -/* - * The heart of the panning operation: - * - * Given a frame buffer position (fb_x, fb_y), - * and a crtc position (crtc_x, crtc_y), - * and a transform matrix which maps frame buffer to crtc, - * compute a panning position (pan_x, pan_y) that - * makes the resulting transform line those two up - */ - -static void -xf86ComputeCrtcPan (Bool sprite_transform_in_use, - struct pixman_f_transform *m, - double screen_x, double screen_y, - double crtc_x, double crtc_y, - int old_pan_x, int old_pan_y, - int *new_pan_x, int *new_pan_y) -{ - if (sprite_transform_in_use) { - /* - * Given the current transform, M, the current position - * on the Screen, S, and the desired position on the CRTC, - * C, compute a translation, T, such that: - * - * M T S = C - * - * where T is of the form - * - * | 1 0 dx | - * | 0 1 dy | - * | 0 0 1 | - * - * M T S = - * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F | - * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F | - * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F | - * - * R = M S - * - * Cx F = M00 dx + M01 dy + R0 - * Cy F = M10 dx + M11 dy + R1 - * F = M20 dx + M21 dy + R2 - * - * Zero out dx, then dy - * - * F (Cx M10 - Cy M00) = - * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1 - * F (M10 - Cy M20) = - * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1 - * - * F (Cx M11 - Cy M01) = - * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1 - * F (M11 - Cy M21) = - * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1 - * - * Make some temporaries - * - * T = | Cx M10 - Cy M00 | - * | Cx M11 - Cy M01 | - * - * U = | M10 M01 - M00 M11 | - * | M11 M00 - M01 M10 | - * - * Q = | M10 R0 - M00 R1 | - * | M11 R0 - M01 R1 | - * - * P = | M10 - Cy M20 | - * | M11 - Cy M21 | - * - * W = | M10 M21 - M20 M11 | - * | M11 M20 - M21 M10 | - * - * V = | M10 R2 - M20 R1 | - * | M11 R2 - M21 R1 | - * - * Rewrite: - * - * F T0 = U0 dy + Q0 - * F P0 = W0 dy + V0 - * F T1 = U1 dx + Q1 - * F P1 = W1 dx + V1 - * - * Solve for F (two ways) - * - * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0 - * - * W0 Q0 - U0 V0 - * F = ------------- - * W0 T0 - U0 P0 - * - * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1 - * - * W1 Q1 - U1 V1 - * F = ------------- - * W1 T1 - U1 P1 - * - * We'll use which ever solution works (denominator != 0) - * - * Finally, solve for dx and dy: - * - * dx = (F T1 - Q1) / U1 - * dx = (F P1 - V1) / W1 - * - * dy = (F T0 - Q0) / U0 - * dy = (F P0 - V0) / W0 - */ - double r[3]; - double q[2], u[2], t[2], v[2], w[2], p[2]; - double f; - struct pict_f_vector d; - int i; - - /* Get the un-normalized crtc coordinates again */ - for (i = 0; i < 3; i++) - r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2]; - - /* Combine values into temporaries */ - for (i = 0; i < 2; i++) { - q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1]; - u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i]; - t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y; - - v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1]; - w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i]; - p[i] = m->m[1][i] - m->m[2][i] * crtc_y; - } - - /* Find a way to compute f */ - f = 0; - for (i = 0; i < 2; i++) { - double a = w[i] * q[i] - u[i] * v[i]; - double b = w[i] * t[i] - u[i] * p[i]; - if (b != 0) { - f = a/b; - break; - } - } - - /* Solve for the resulting transform vector */ - for (i = 0; i < 2; i++) { - if (u[i]) - d.v[1-i] = (t[i] * f - q[i]) / u[i]; - else if (w[1]) - d.v[1-i] = (p[i] * f - v[i]) / w[i]; - else - d.v[1-i] = 0; - } - *new_pan_x = old_pan_x - floor (d.v[0] + 0.5); - *new_pan_y = old_pan_y - floor (d.v[1] + 0.5); - } else { - *new_pan_x = screen_x - crtc_x; - *new_pan_y = screen_y - crtc_y; - } -} - -static void -xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y) -{ - int newX, newY; - int width, height; - Bool panned = FALSE; - - if (crtc->version < 2) - return; - - if (! crtc->enabled || - (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 && - crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1)) - return; - - newX = crtc->x; - newY = crtc->y; - width = crtc->mode.HDisplay; - height = crtc->mode.VDisplay; - - if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 || - (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) && - (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 || - (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2))) - { - struct pict_f_vector c; - - /* - * Pre-clip the mouse position to the panning area so that we don't - * push the crtc outside. This doesn't deal with changes to the - * panning values, only mouse position changes. - */ - if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) - { - if (x < crtc->panningTotalArea.x1) - x = crtc->panningTotalArea.x1; - if (x >= crtc->panningTotalArea.x2) - x = crtc->panningTotalArea.x2 - 1; - } - if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) - { - if (y < crtc->panningTotalArea.y1) - y = crtc->panningTotalArea.y1; - if (y >= crtc->panningTotalArea.y2) - y = crtc->panningTotalArea.y2 - 1; - } - - c.v[0] = x; - c.v[1] = y; - c.v[2] = 1.0; - if (crtc->sprite_transform_in_use) { - pixman_f_transform_point(&crtc->f_screen_to_crtc, &c); - } else { - c.v[0] -= crtc->x; - c.v[1] -= crtc->y; - } - - if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) { - if (c.v[0] < crtc->panningBorder[0]) { - c.v[0] = crtc->panningBorder[0]; - panned = TRUE; - } - if (c.v[0] >= width - crtc->panningBorder[2]) { - c.v[0] = width - crtc->panningBorder[2] - 1; - panned = TRUE; - } - } - if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { - if (c.v[1] < crtc->panningBorder[1]) { - c.v[1] = crtc->panningBorder[1]; - panned = TRUE; - } - if (c.v[1] >= height - crtc->panningBorder[3]) { - c.v[1] = height - crtc->panningBorder[3] - 1; - panned = TRUE; - } - } - if (panned) - xf86ComputeCrtcPan (crtc->sprite_transform_in_use, - &crtc->f_screen_to_crtc, - x, y, c.v[0], c.v[1], - newX, newY, &newX, &newY); - } - - /* - * Ensure that the crtc is within the panning region. - * - * XXX This computation only works when we do not have a transform - * in use. - */ - if (!crtc->sprite_transform_in_use) - { - /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */ - if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) { - if (newX > crtc->panningTotalArea.x2 - width) - newX = crtc->panningTotalArea.x2 - width; - if (newX < crtc->panningTotalArea.x1) - newX = crtc->panningTotalArea.x1; - } - if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { - if (newY > crtc->panningTotalArea.y2 - height) - newY = crtc->panningTotalArea.y2 - height; - if (newY < crtc->panningTotalArea.y1) - newY = crtc->panningTotalArea.y1; - } - } - if (newX != crtc->x || newY != crtc->y) - xf86CrtcSetOrigin (crtc, newX, newY); -} - -static Bool -xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations) -{ - RRScreenSizePtr pSize; - ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - DisplayModePtr mode; - int refresh0 = 60; - int maxX = 0, maxY = 0; - - *rotations = randrp->supported_rotations; - - if (randrp->virtualX == -1 || randrp->virtualY == -1) - { - randrp->virtualX = scrp->virtualX; - randrp->virtualY = scrp->virtualY; - } - - /* Re-probe the outputs for new monitors or modes */ - if (scrp->vtSema) - { - xf86ProbeOutputModes (scrp, 0, 0); - xf86SetScrnInfoModes (scrp); - } - - for (mode = scrp->modes; ; mode = mode->next) - { - int refresh = xf86RandR12ModeRefresh (mode); - if (randrp->maxX == 0 || randrp->maxY == 0) - { - if (maxX < mode->HDisplay) - maxX = mode->HDisplay; - if (maxY < mode->VDisplay) - maxY = mode->VDisplay; - } - if (mode == scrp->modes) - refresh0 = refresh; - pSize = RRRegisterSize (pScreen, - mode->HDisplay, mode->VDisplay, - randrp->mmWidth, randrp->mmHeight); - if (!pSize) - return FALSE; - RRRegisterRate (pScreen, pSize, refresh); - - if (xf86ModesEqual(mode, scrp->currentMode)) - { - RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize); - } - if (mode->next == scrp->modes) - break; - } - - if (randrp->maxX == 0 || randrp->maxY == 0) - { - randrp->maxX = maxX; - randrp->maxY = maxY; - } - - return TRUE; -} - -static Bool -xf86RandR12SetMode (ScreenPtr pScreen, - DisplayModePtr mode, - Bool useVirtual, - int mmWidth, - int mmHeight) -{ - ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - int oldWidth = pScreen->width; - int oldHeight = pScreen->height; - int oldmmWidth = pScreen->mmWidth; - int oldmmHeight = pScreen->mmHeight; - WindowPtr pRoot = pScreen->root; - DisplayModePtr currentMode = NULL; - Bool ret = TRUE; - - if (pRoot) - (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE); - if (useVirtual) - { - scrp->virtualX = randrp->virtualX; - scrp->virtualY = randrp->virtualY; - } - else - { - scrp->virtualX = mode->HDisplay; - scrp->virtualY = mode->VDisplay; - } - - if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270)) - { - /* If the screen is rotated 90 or 270 degrees, swap the sizes. */ - pScreen->width = scrp->virtualY; - pScreen->height = scrp->virtualX; - pScreen->mmWidth = mmHeight; - pScreen->mmHeight = mmWidth; - } - else - { - pScreen->width = scrp->virtualX; - pScreen->height = scrp->virtualY; - pScreen->mmWidth = mmWidth; - pScreen->mmHeight = mmHeight; - } - if (scrp->currentMode == mode) { - /* Save current mode */ - currentMode = scrp->currentMode; - /* Reset, just so we ensure the drivers SwitchMode is called */ - scrp->currentMode = NULL; - } - /* - * We know that if the driver failed to SwitchMode to the rotated - * version, then it should revert back to it's prior mode. - */ - if (!xf86SwitchMode (pScreen, mode)) - { - ret = FALSE; - scrp->virtualX = pScreen->width = oldWidth; - scrp->virtualY = pScreen->height = oldHeight; - pScreen->mmWidth = oldmmWidth; - pScreen->mmHeight = oldmmHeight; - scrp->currentMode = currentMode; - } - - /* - * Make sure the layout is correct - */ - xf86ReconfigureLayout(); - - /* - * Make sure the whole screen is visible - */ - xf86SetViewport (pScreen, pScreen->width, pScreen->height); - xf86SetViewport (pScreen, 0, 0); - if (pRoot) - (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE); - return ret; -} - -Bool -xf86RandR12SetConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - DisplayModePtr mode; - int px, py; - Bool useVirtual = FALSE; - int maxX = 0, maxY = 0; - Rotation oldRotation = randrp->rotation; - - randrp->rotation = rotation; - - if (randrp->virtualX == -1 || randrp->virtualY == -1) - { - randrp->virtualX = scrp->virtualX; - randrp->virtualY = scrp->virtualY; - } - - miPointerGetPosition (inputInfo.pointer, &px, &py); - for (mode = scrp->modes; ; mode = mode->next) - { - if (randrp->maxX == 0 || randrp->maxY == 0) - { - if (maxX < mode->HDisplay) - maxX = mode->HDisplay; - if (maxY < mode->VDisplay) - maxY = mode->VDisplay; - } - if (mode->HDisplay == pSize->width && - mode->VDisplay == pSize->height && - (rate == 0 || xf86RandR12ModeRefresh (mode) == rate)) - break; - if (mode->next == scrp->modes) - { - if (pSize->width == randrp->virtualX && - pSize->height == randrp->virtualY) - { - mode = scrp->modes; - useVirtual = TRUE; - break; - } - if (randrp->maxX == 0 || randrp->maxY == 0) - { - randrp->maxX = maxX; - randrp->maxY = maxY; - } - return FALSE; - } - } - - if (randrp->maxX == 0 || randrp->maxY == 0) - { - randrp->maxX = maxX; - randrp->maxY = maxY; - } - - if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth, - pSize->mmHeight)) { - randrp->rotation = oldRotation; - return FALSE; - } - - /* - * Move the cursor back where it belongs; SwitchMode repositions it - */ - if (pScreen == miPointerGetScreen(inputInfo.pointer)) - { - px = (px >= pScreen->width ? (pScreen->width - 1) : px); - py = (py >= pScreen->height ? (pScreen->height - 1) : py); - - xf86SetViewport(pScreen, px, py); - - (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE); - } - - return TRUE; -} - -static Bool -xf86RandR12ScreenSetSize (ScreenPtr pScreen, - CARD16 width, - CARD16 height, - CARD16 pixWidth, - CARD16 pixHeight, - CARD32 mmWidth, - CARD32 mmHeight) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - WindowPtr pRoot = pScreen->root; - PixmapPtr pScrnPix; - Bool ret = FALSE; - Bool pixSizeChanged = FALSE; - Bool winSizeChanged = FALSE; - int c; - - if (xf86RandR12Key) { - if (randrp->virtualX == -1 || randrp->virtualY == -1) - { - randrp->virtualX = pScrn->virtualX; - randrp->virtualY = pScrn->virtualY; - pixSizeChanged = TRUE; - } - } - - pScrnPix = (*pScreen->GetScreenPixmap)(pScreen); - if (pixWidth != pScrnPix->drawable.width || - pixHeight != pScrnPix->drawable.height) - pixSizeChanged = TRUE; - - if (width != pScreen->width || height != pScreen->height) - winSizeChanged = TRUE; - - if (pixSizeChanged) - { - if (pRoot && pScrn->vtSema) - (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE); - - /* Let the driver update virtualX and virtualY */ - if (!(*config->funcs->resize)(pScrn, pixWidth, pixHeight)) - goto finish; - } - - ret = TRUE; - - if (winSizeChanged) - { - /* Update panning information */ - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 || - crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { - if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1) - crtc->panningTotalArea.x2 += width - pScreen->width; - if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1) - crtc->panningTotalArea.y2 += height - pScreen->height; - if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1) - crtc->panningTrackingArea.x2 += width - pScreen->width; - if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1) - crtc->panningTrackingArea.y2 += height - pScreen->height; - xf86RandR13VerifyPanningArea (crtc, width, height); - xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); - } - } - } - - pScrnPix = (*pScreen->GetScreenPixmap)(pScreen); - pScreen->width = width; - pScreen->height = height; - if (pRoot) - { - BoxRec box; - - pRoot->drawable.width = width; - pRoot->drawable.height = height; - box.x1 = 0; - box.y1 = 0; - box.x2 = width; - box.y2 = height; - RegionInit(&pRoot->winSize, &box, 1); - RegionInit(&pRoot->borderSize, &box, 1); - } - pScrnPix->drawable.width = pixWidth; - pScrnPix->drawable.height = pixHeight; - randrp->mmWidth = pScreen->mmWidth = mmWidth; - randrp->mmHeight = pScreen->mmHeight = mmHeight; - - if (winSizeChanged) - { - xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1); - xf86SetViewport (pScreen, 0, 0); - } - -finish: - if (pixSizeChanged) - { - if (pRoot && pScrn->vtSema) - (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); - } - -#if RANDR_12_INTERFACE - if (xf86RandR12Key && pScreen->root && ret) - RRScreenSizeNotify (pScreen); -#endif - return ret; -} - -Rotation -xf86RandR12GetRotation(ScreenPtr pScreen) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - - return randrp->rotation; -} - -Bool -xf86RandR12CreateScreenResources (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config; - XF86RandRInfoPtr randrp; - int c; - int width, height; - int mmWidth, mmHeight; -#ifdef PANORAMIX - /* XXX disable RandR when using Xinerama */ - if (!noPanoramiXExtension) - return TRUE; -#endif - - config = XF86_CRTC_CONFIG_PTR(pScrn); - randrp = XF86RANDRINFO(pScreen); - /* - * Compute size of screen - */ - width = 0; height = 0; - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation); - int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation); - - if (crtc->enabled) { - if (crtc_width > width) - width = crtc_width; - if (crtc_height > height) - height = crtc_height; - if (crtc->panningTotalArea.x2 > width) - width = crtc->panningTotalArea.x2; - if (crtc->panningTotalArea.y2 > height) - height = crtc->panningTotalArea.y2; - } - } - - if (width && height) - { - /* - * Compute physical size of screen - */ - if (monitorResolution) - { - mmWidth = width * 25.4 / monitorResolution; - mmHeight = height * 25.4 / monitorResolution; - } - else - { - xf86OutputPtr output = xf86CompatOutput(pScrn); - - if (output && - output->conf_monitor && - (output->conf_monitor->mon_width > 0 && - output->conf_monitor->mon_height > 0)) - { - /* - * Prefer user configured DisplaySize - */ - mmWidth = output->conf_monitor->mon_width; - mmHeight = output->conf_monitor->mon_height; - } - else - { - /* - * Otherwise, just set the screen to DEFAULT_DPI - */ - mmWidth = width * 25.4 / DEFAULT_DPI; - mmHeight = height * 25.4 / DEFAULT_DPI; - } - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Setting screen physical size to %d x %d\n", - mmWidth, mmHeight); - /* - * This is the initial setting of the screen size. - * We have to pre-set it here, otherwise panning would be adapted - * to the new screen size. - */ - pScreen->width = width; - pScreen->height = height; - xf86RandR12ScreenSetSize (pScreen, - width, - height, - width, - height, - mmWidth, - mmHeight); - } - - if (xf86RandR12Key == NULL) - return TRUE; - - if (randrp->virtualX == -1 || randrp->virtualY == -1) - { - randrp->virtualX = pScrn->virtualX; - randrp->virtualY = pScrn->virtualY; - } - xf86CrtcSetScreenSubpixelOrder (pScreen); -#if RANDR_12_INTERFACE - if (xf86RandR12CreateScreenResources12 (pScreen)) - return TRUE; -#endif - return TRUE; -} - - -Bool -xf86RandR12Init (ScreenPtr pScreen) -{ - rrScrPrivPtr rp; - XF86RandRInfoPtr randrp; - -#ifdef PANORAMIX - /* XXX disable RandR when using Xinerama */ - if (!noPanoramiXExtension) - { - if (xf86NumScreens == 1) - noPanoramiXExtension = TRUE; - else - return TRUE; - } -#endif - - if (xf86RandR12Generation != serverGeneration) - xf86RandR12Generation = serverGeneration; - - xf86RandR12Key = &xf86RandR12KeyRec; - if (!dixRegisterPrivateKey(&xf86RandR12KeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - - randrp = malloc(sizeof (XF86RandRInfoRec)); - if (!randrp) - return FALSE; - - if (!RRScreenInit(pScreen)) - { - free(randrp); - return FALSE; - } - rp = rrGetScrPriv(pScreen); - rp->rrGetInfo = xf86RandR12GetInfo; - rp->rrSetConfig = xf86RandR12SetConfig; - - randrp->virtualX = -1; - randrp->virtualY = -1; - randrp->mmWidth = pScreen->mmWidth; - randrp->mmHeight = pScreen->mmHeight; - - randrp->rotation = RR_Rotate_0; /* initial rotated mode */ - - randrp->supported_rotations = RR_Rotate_0; - - randrp->maxX = randrp->maxY = 0; - - dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp); - -#if RANDR_12_INTERFACE - if (!xf86RandR12Init12 (pScreen)) - return FALSE; -#endif - return TRUE; -} - -void -xf86RandR12CloseScreen (ScreenPtr pScreen) -{ - XF86RandRInfoPtr randrp; - - if (xf86RandR12Key == NULL) - return; - - randrp = XF86RANDRINFO(pScreen); -#if RANDR_12_INTERFACE - xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT; -#endif - - free(randrp); -} - -void -xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) -{ - XF86RandRInfoPtr randrp; -#if RANDR_12_INTERFACE - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - int c; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); -#endif - - if (xf86RandR12Key == NULL) - return; - - randrp = XF86RANDRINFO(pScreen); -#if RANDR_12_INTERFACE - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - - RRCrtcSetRotations (crtc->randr_crtc, rotations); - } -#endif - randrp->supported_rotations = rotations; -} - -void -xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms) -{ - XF86RandRInfoPtr randrp; -#if RANDR_13_INTERFACE - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - int c; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); -#endif - - if (xf86RandR12Key == NULL) - return; - - randrp = XF86RANDRINFO(pScreen); -#if RANDR_13_INTERFACE - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - - RRCrtcSetTransformSupport (crtc->randr_crtc, transforms); - } -#endif -} - -void -xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y) -{ - ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - - if (xf86RandR12Generation != serverGeneration || - XF86RANDRINFO(pScreen)->virtualX == -1) - { - *x = pScrn->virtualX; - *y = pScrn->virtualY; - } else { - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - - *x = randrp->virtualX; - *y = randrp->virtualY; - } -} - -#if RANDR_12_INTERFACE - -#define FLAG_BITS (RR_HSyncPositive | \ - RR_HSyncNegative | \ - RR_VSyncPositive | \ - RR_VSyncNegative | \ - RR_Interlace | \ - RR_DoubleScan | \ - RR_CSync | \ - RR_CSyncPositive | \ - RR_CSyncNegative | \ - RR_HSkewPresent | \ - RR_BCast | \ - RR_PixelMultiplex | \ - RR_DoubleClock | \ - RR_ClockDivideBy2) - -static Bool -xf86RandRModeMatches (RRModePtr randr_mode, - DisplayModePtr mode) -{ -#if 0 - if (match_name) - { - /* check for same name */ - int len = strlen (mode->name); - if (randr_mode->mode.nameLength != len) return FALSE; - if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE; - } -#endif - - /* check for same timings */ - if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE; - if (randr_mode->mode.width != mode->HDisplay) return FALSE; - if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE; - if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE; - if (randr_mode->mode.hTotal != mode->HTotal) return FALSE; - if (randr_mode->mode.hSkew != mode->HSkew) return FALSE; - if (randr_mode->mode.height != mode->VDisplay) return FALSE; - if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE; - if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE; - if (randr_mode->mode.vTotal != mode->VTotal) return FALSE; - - /* check for same flags (using only the XF86 valid flag bits) */ - if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS)) - return FALSE; - - /* everything matches */ - return TRUE; -} - -static Bool -xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) -{ - ScreenPtr pScreen = randr_crtc->pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - RRModePtr randr_mode = NULL; - int x; - int y; - Rotation rotation; - int numOutputs; - RROutputPtr *randr_outputs; - RROutputPtr randr_output; - xf86CrtcPtr crtc = randr_crtc->devPrivate; - xf86OutputPtr output; - int i, j; - DisplayModePtr mode = &crtc->mode; - Bool ret; - - randr_outputs = malloc(config->num_output * sizeof (RROutputPtr)); - if (!randr_outputs) - return FALSE; - x = crtc->x; - y = crtc->y; - rotation = crtc->rotation; - numOutputs = 0; - randr_mode = NULL; - for (i = 0; i < config->num_output; i++) - { - output = config->output[i]; - if (output->crtc == crtc) - { - randr_output = output->randr_output; - randr_outputs[numOutputs++] = randr_output; - /* - * We make copies of modes, so pointer equality - * isn't sufficient - */ - for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++) - { - RRModePtr m = (j < randr_output->numModes ? - randr_output->modes[j] : - randr_output->userModes[j-randr_output->numModes]); - - if (xf86RandRModeMatches (m, mode)) - { - randr_mode = m; - break; - } - } - } - } - ret = RRCrtcNotify (randr_crtc, randr_mode, x, y, - rotation, - crtc->transformPresent ? &crtc->transform : NULL, - numOutputs, randr_outputs, crtc->scanoutPixmap); - free(randr_outputs); - return ret; -} - -/* - * Convert a RandR mode to a DisplayMode - */ -static void -xf86RandRModeConvert (ScrnInfoPtr scrn, - RRModePtr randr_mode, - DisplayModePtr mode) -{ - memset(mode, 0, sizeof(DisplayModeRec)); - mode->status = MODE_OK; - - mode->Clock = randr_mode->mode.dotClock / 1000; - - mode->HDisplay = randr_mode->mode.width; - mode->HSyncStart = randr_mode->mode.hSyncStart; - mode->HSyncEnd = randr_mode->mode.hSyncEnd; - mode->HTotal = randr_mode->mode.hTotal; - mode->HSkew = randr_mode->mode.hSkew; - - mode->VDisplay = randr_mode->mode.height; - mode->VSyncStart = randr_mode->mode.vSyncStart; - mode->VSyncEnd = randr_mode->mode.vSyncEnd; - mode->VTotal = randr_mode->mode.vTotal; - mode->VScan = 0; - - mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS; - - xf86SetModeCrtc (mode, scrn->adjustFlags); -} - -static Bool -xf86RandR12CrtcSet (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - RRModePtr randr_mode, - int x, - int y, - Rotation rotation, - int num_randr_outputs, - RROutputPtr *randr_outputs, - PixmapPtr scanout_pixmap) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86CrtcPtr crtc = randr_crtc->devPrivate; - RRTransformPtr transform; - xf86CrtcSetFlags flags = 0; - int o, ro; - xf86CrtcPtr *save_crtcs; - Bool save_enabled = crtc->enabled; - - if (!crtc->scrn->vtSema) - return FALSE; - - save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr)); - if ((randr_mode != NULL) != crtc->enabled) - flags |= XF86CrtcSetMode; - else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode)) - flags |= XF86CrtcSetMode; - - if (rotation != crtc->rotation) - flags |= XF86CrtcSetRotation; - - transform = RRCrtcGetTransform (randr_crtc); - if ((transform != NULL) != crtc->transformPresent) - flags |= XF86CrtcSetTransform; - else if (transform && memcmp (&transform->transform, &crtc->transform.transform, - sizeof (transform->transform)) != 0) - flags |= XF86CrtcSetTransform; - - if (scanout_pixmap != crtc->scanoutPixmap) - flags |= XF86CrtcSetScanoutPixmap; - - if (x != crtc->x || y != crtc->y) - flags |= XF86CrtcSetOrigin; - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - xf86CrtcPtr new_crtc; - - save_crtcs[o] = output->crtc; - - if (output->crtc == crtc) - new_crtc = NULL; - else - new_crtc = output->crtc; - for (ro = 0; ro < num_randr_outputs; ro++) - if (output->randr_output == randr_outputs[ro]) - { - new_crtc = crtc; - break; - } - if (new_crtc != output->crtc) - { - flags |= XF86CrtcSetOutput; - output->crtc = new_crtc; - } - } - for (ro = 0; ro < num_randr_outputs; ro++) - if (randr_outputs[ro]->pendingProperties) - flags |= XF86CrtcSetProperty; - - /* XXX need device-independent mode setting code through an API */ - if (flags) - { - crtc->enabled = randr_mode != NULL; - - if (randr_mode) - { - DisplayModeRec mode; - RRTransformPtr transform = RRCrtcGetTransform (randr_crtc); - xf86CrtcSetRec set; - - xf86RandRModeConvert (pScrn, randr_mode, &mode); - set.mode = &mode; - set.rotation = rotation; - set.transform = transform; - set.x = x; - set.y = y; - set.scanout_pixmap = scanout_pixmap; - set.flags = flags; - if (!xf86CrtcSet(crtc, &set)) - { - crtc->enabled = save_enabled; - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - output->crtc = save_crtcs[o]; - } - free(save_crtcs); - return FALSE; - } - xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height); - xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); - /* - * Save the last successful setting for EnterVT - */ - crtc->desiredMode = mode; - crtc->desiredRotation = rotation; - if (transform) { - crtc->desiredTransform = *transform; - crtc->desiredTransformPresent = TRUE; - } else - crtc->desiredTransformPresent = FALSE; - - crtc->desiredX = x; - crtc->desiredY = y; - } - xf86DisableUnusedFunctions (pScrn); - } - free(save_crtcs); - return xf86RandR12CrtcNotify (randr_crtc); -} - -static Bool -xf86RandR12CrtcSetGamma (ScreenPtr pScreen, - RRCrtcPtr randr_crtc) -{ - xf86CrtcPtr crtc = randr_crtc->devPrivate; - - if (crtc->funcs->gamma_set == NULL) - return FALSE; - - if (!crtc->scrn->vtSema) - return TRUE; - - /* Realloc local gamma if needed. */ - if (randr_crtc->gammaSize != crtc->gamma_size) { - CARD16 *tmp_ptr; - tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16)); - if (!tmp_ptr) - return FALSE; - crtc->gamma_red = tmp_ptr; - crtc->gamma_green = crtc->gamma_red + crtc->gamma_size; - crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size; - } - - crtc->gamma_size = randr_crtc->gammaSize; - memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16)); - memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16)); - memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16)); - - /* Only set it when the crtc is actually running. - * Otherwise it will be set when it's activated. - */ - if (crtc->active) - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); - - return TRUE; -} - -static Bool -xf86RandR12CrtcGetGamma (ScreenPtr pScreen, - RRCrtcPtr randr_crtc) -{ - xf86CrtcPtr crtc = randr_crtc->devPrivate; - - if (!crtc->gamma_size) - return FALSE; - - if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue) - return FALSE; - - /* Realloc randr gamma if needed. */ - if (randr_crtc->gammaSize != crtc->gamma_size) { - CARD16 *tmp_ptr; - tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16)); - if (!tmp_ptr) - return FALSE; - randr_crtc->gammaRed = tmp_ptr; - randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size; - randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size; - } - randr_crtc->gammaSize = crtc->gamma_size; - memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16)); - memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16)); - memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16)); - - return TRUE; -} - -static Bool -xf86RandR12OutputSetProperty (ScreenPtr pScreen, - RROutputPtr randr_output, - Atom property, - RRPropertyValuePtr value) -{ - xf86OutputPtr output = randr_output->devPrivate; - - /* If we don't have any property handler, then we don't care what the - * user is setting properties to. - */ - if (output->funcs->set_property == NULL) - return TRUE; - - /* - * This function gets called even when vtSema is FALSE, as - * drivers will need to remember the correct value to apply - * when the VT switch occurs - */ - return output->funcs->set_property(output, property, value); -} - -static Bool -xf86RandR13OutputGetProperty (ScreenPtr pScreen, - RROutputPtr randr_output, - Atom property) -{ - xf86OutputPtr output = randr_output->devPrivate; - - if (output->funcs->get_property == NULL) - return TRUE; - - /* Should be safe even w/o vtSema */ - return output->funcs->get_property(output, property); -} - -static Bool -xf86RandR12OutputValidateMode (ScreenPtr pScreen, - RROutputPtr randr_output, - RRModePtr randr_mode) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86OutputPtr output = randr_output->devPrivate; - DisplayModeRec mode; - - xf86RandRModeConvert (pScrn, randr_mode, &mode); - /* - * This function may be called when vtSema is FALSE, so - * the underlying function must either avoid touching the hardware - * or return FALSE when vtSema is FALSE - */ - if (output->funcs->mode_valid (output, &mode) != MODE_OK) - return FALSE; - return TRUE; -} - -static void -xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode) -{ -} - -/** - * Given a list of xf86 modes and a RandR Output object, construct - * RandR modes and assign them to the output - */ -static Bool -xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes) -{ - DisplayModePtr mode; - RRModePtr *rrmodes = NULL; - int nmode = 0; - int npreferred = 0; - Bool ret = TRUE; - int pref; - - for (mode = modes; mode; mode = mode->next) - nmode++; - - if (nmode) { - rrmodes = malloc(nmode * sizeof (RRModePtr)); - - if (!rrmodes) - return FALSE; - nmode = 0; - - for (pref = 1; pref >= 0; pref--) { - for (mode = modes; mode; mode = mode->next) { - if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) { - xRRModeInfo modeInfo; - RRModePtr rrmode; - - modeInfo.nameLength = strlen (mode->name); - modeInfo.width = mode->HDisplay; - modeInfo.dotClock = mode->Clock * 1000; - modeInfo.hSyncStart = mode->HSyncStart; - modeInfo.hSyncEnd = mode->HSyncEnd; - modeInfo.hTotal = mode->HTotal; - modeInfo.hSkew = mode->HSkew; - - modeInfo.height = mode->VDisplay; - modeInfo.vSyncStart = mode->VSyncStart; - modeInfo.vSyncEnd = mode->VSyncEnd; - modeInfo.vTotal = mode->VTotal; - modeInfo.modeFlags = mode->Flags; - - rrmode = RRModeGet (&modeInfo, mode->name); - if (rrmode) { - rrmodes[nmode++] = rrmode; - npreferred += pref; - } - } - } - } - } - - ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred); - free(rrmodes); - return ret; -} - -/* - * Mirror the current mode configuration to RandR - */ -static Bool -xf86RandR12SetInfo12 (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - RROutputPtr *clones; - RRCrtcPtr *crtcs; - int ncrtc; - int o, c, l; - RRCrtcPtr randr_crtc; - int nclone; - - clones = malloc(config->num_output * sizeof (RROutputPtr)); - crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr)); - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - ncrtc = 0; - for (c = 0; c < config->num_crtc; c++) - if (output->possible_crtcs & (1 << c)) - crtcs[ncrtc++] = config->crtc[c]->randr_crtc; - - if (output->crtc) - randr_crtc = output->crtc->randr_crtc; - else - randr_crtc = NULL; - - if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc)) - { - free(crtcs); - free(clones); - return FALSE; - } - - RROutputSetPhysicalSize(output->randr_output, - output->mm_width, - output->mm_height); - xf86RROutputSetModes (output->randr_output, output->probed_modes); - - switch (output->status) { - case XF86OutputStatusConnected: - RROutputSetConnection (output->randr_output, RR_Connected); - break; - case XF86OutputStatusDisconnected: - RROutputSetConnection (output->randr_output, RR_Disconnected); - break; - case XF86OutputStatusUnknown: - RROutputSetConnection (output->randr_output, RR_UnknownConnection); - break; - } - - RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order); - - /* - * Valid clones - */ - nclone = 0; - for (l = 0; l < config->num_output; l++) - { - xf86OutputPtr clone = config->output[l]; - - if (l != o && (output->possible_clones & (1 << l))) - clones[nclone++] = clone->randr_output; - } - if (!RROutputSetClones (output->randr_output, clones, nclone)) - { - free(crtcs); - free(clones); - return FALSE; - } - } - free(crtcs); - free(clones); - return TRUE; -} - - - -/* - * Query the hardware for the current state, then mirror - * that to RandR - */ -static Bool -xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - - if (!pScrn->vtSema) - return TRUE; - xf86ProbeOutputModes (pScrn, 0, 0); - xf86SetScrnInfoModes (pScrn); - return xf86RandR12SetInfo12 (pScreen); -} - -static Bool -xf86RandR12CreateObjects12 (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - int o; - - if (!RRInit ()) - return FALSE; - - /* - * Configure crtcs - */ - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - - crtc->randr_crtc = RRCrtcCreate (pScreen, crtc); - RRCrtcGammaSetSize (crtc->randr_crtc, 256); - } - /* - * Configure outputs - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - output->randr_output = RROutputCreate (pScreen, output->name, - strlen (output->name), - output); - - if (output->funcs->create_resources != NULL) - output->funcs->create_resources(output); - RRPostPendingProperties (output->randr_output); - } - return TRUE; -} - -static Bool -xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) -{ - int c; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - - if (xf86RandR12Key == NULL) - return TRUE; - - for (c = 0; c < config->num_crtc; c++) - xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); - - RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight, - config->maxWidth, config->maxHeight); - return TRUE; -} - -/* - * Something happened within the screen configuration due - * to DGA, VidMode or hot key. Tell RandR - */ - -void -xf86RandR12TellChanged (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - - if (xf86RandR12Key == NULL) - return; - - xf86RandR12SetInfo12 (pScreen); - for (c = 0; c < config->num_crtc; c++) - xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); - - RRTellChanged (pScreen); -} - -static void -xf86RandR12PointerMoved (int scrnIndex, int x, int y) -{ - ScreenPtr pScreen = screenInfo.screens[scrnIndex]; - ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - int c; - - randrp->pointerX = x; - randrp->pointerY = y; - for (c = 0; c < config->num_crtc; c++) - xf86RandR13Pan (config->crtc[c], x, y); -} - -static Bool -xf86RandR13GetPanning (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - BoxPtr totalArea, - BoxPtr trackingArea, - INT16 *border) -{ - xf86CrtcPtr crtc = randr_crtc->devPrivate; - - if (crtc->version < 2) - return FALSE; - if (totalArea) - memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec)); - if (trackingArea) - memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec)); - if (border) - memcpy (border, crtc->panningBorder, 4*sizeof(INT16)); - - return TRUE; -} - -static Bool -xf86RandR13SetPanning (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - BoxPtr totalArea, - BoxPtr trackingArea, - INT16 *border) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - xf86CrtcPtr crtc = randr_crtc->devPrivate; - BoxRec oldTotalArea; - BoxRec oldTrackingArea; - INT16 oldBorder[4]; - - - if (crtc->version < 2) - return FALSE; - - memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec)); - memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec)); - memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16)); - - if (totalArea) - memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec)); - if (trackingArea) - memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec)); - if (border) - memcpy (crtc->panningBorder, border, 4*sizeof(INT16)); - - if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) { - xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); - return TRUE; - } else { - /* Restore old settings */ - memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec)); - memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec)); - memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16)); - return FALSE; - } -} - -/* - * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers - * any per-crtc setup. You asked for it... - */ - -static void -gamma_to_ramp(float gamma, CARD16 *ramp, int size) -{ - int i; - - for (i = 0; i < size; i++) { - if (gamma == 1.0) - ramp[i] = i << 8; - else - ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma) - * (double)(size - 1) * 256); - } -} - -static int -xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma) -{ - CARD16 *points, *red, *green, *blue; - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn); - int size; - - if (!crtc) - return Success; - - size = max(0, crtc->gammaSize); - if (!size) - return Success; - - points = calloc(size, 3 * sizeof(CARD16)); - if (!points) - return BadAlloc; - - red = points; - green = points + size; - blue = points + 2 * size; - - gamma_to_ramp(gamma.red, red, size); - gamma_to_ramp(gamma.green, green, size); - gamma_to_ramp(gamma.blue, blue, size); - RRCrtcGammaSet(crtc, red, green, blue); - - free(points); - - pScrn->gamma = gamma; - - return Success; -} - -static RRScanoutPixmapInfo * -xf86RRQueryScanoutPixmaps(ScreenPtr screen, int *n_info) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - RRScanoutPixmapInfo *info; - int f; - - info = calloc(config->num_scanout_formats, sizeof (RRScanoutPixmapInfo)); - if (config->num_scanout_formats && !info) { - *n_info = 0; - return NULL; - } - for (f = 0; f < config->num_scanout_formats; f++) { - info[f].maxWidth = config->scanout_formats[f].maxWidth; - info[f].maxHeight = config->scanout_formats[f].maxHeight; - info[f].depth = config->scanout_formats[f].depth; - info[f].rotations = config->scanout_formats[f].rotations; - info[f].format = PictureMatchFormat (screen, info[f].depth, - config->scanout_formats[f].format); - } - *n_info = config->num_scanout_formats; - return info; -} - -static PixmapPtr -xf86RRCreateScanoutPixmap(ScreenPtr screen, - int width, int height, int depth, - Rotation rotations, - PictFormatPtr format) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int f; - - if (!config->funcs->create_scanout_pixmap) - return NullPixmap; - - for (f = 0; f < config->num_scanout_formats; f++) - if (config->scanout_formats[f].depth == depth && - (config->scanout_formats[f].format & 0xffffff) == format->format) { - return (*config->funcs->create_scanout_pixmap) (scrn, width, height, - rotations, - &config->scanout_formats[f]); - } - return NullPixmap; -} - -static void -xf86RandR14SetCrtcSpriteTransform(ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - struct pixman_f_transform *f_position_transform, - struct pixman_f_transform *f_image_transform) -{ - xf86CrtcPtr crtc = randr_crtc->devPrivate; - - crtc->user_sprite_position_transform = *f_position_transform; - crtc->user_sprite_image_transform = *f_image_transform; - xf86CrtcRotateCursor(crtc); - xf86_reload_cursors(pScreen); -} - -static Bool -xf86RRConvertCrtcConfig(xf86CrtcSetConfigPtr xf86_config, - RRCrtcConfigPtr rr_config) -{ - RRCrtcPtr rr_crtc = rr_config->crtc; - xf86CrtcPtr crtc = rr_crtc->devPrivate; - ScrnInfoPtr scrn = xf86Screens[rr_crtc->pScreen->myNum]; - int o; - - xf86_config->crtc = crtc; - xf86_config->x = rr_config->x; - xf86_config->y = rr_config->y; - xf86RandRModeConvert(scrn, rr_config->mode, &xf86_config->mode); - xf86_config->rotation = rr_config->rotation; - xf86_config->numOutputs = rr_config->numOutputs; - xf86_config->outputs = calloc(rr_config->numOutputs, sizeof (xf86OutputPtr)); - if (!xf86_config->outputs) - return FALSE; - for (o = 0; o < rr_config->numOutputs; o++) - xf86_config->outputs[o] = rr_config->outputs[o]->devPrivate; - xf86_config->sprite_position_transform = rr_config->sprite_position_f_transform; - xf86_config->sprite_image_transform = rr_config->sprite_image_f_transform; - xf86_config->pixmap = rr_config->pixmap; - xf86_config->pixmap_x = rr_config->pixmap_x; - xf86_config->pixmap_y = rr_config->pixmap_y; - return TRUE; -} - -static void -xf86FreeCrtcSetConfigs(xf86CrtcSetConfigPtr xf86_crtc_configs, int num_configs) -{ - int i; - - for (i = 0; i < num_configs; i++) - free(xf86_crtc_configs[i].outputs); - free(xf86_crtc_configs); -} - -static Bool -xf86RRSetCrtcConfigs(ScreenPtr screen, - RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_configs, - int num_configs) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - - if (config->funcs->set_config) { - xf86CrtcSetConfigPtr xf86_crtc_configs; - int i; - xf86SetConfigResponse response; - - /* - * Convert RRCrtcConfigRecs to xf86CrtcSetConfigs - */ - xf86_crtc_configs = calloc(num_configs, sizeof (xf86CrtcSetConfigRec)); - if (!xf86_crtc_configs) - return FALSE; - for (i = 0; i < num_configs; i++) - if (!xf86RRConvertCrtcConfig(&xf86_crtc_configs[i], &crtc_configs[i])) { - xf86FreeCrtcSetConfigs(xf86_crtc_configs, num_configs); - return FALSE; - } - - /* - * Ask the driver to set the configuration - */ - response = (*config->funcs->set_config)(scrn, - screen_config, - xf86_crtc_configs, - num_configs); - xf86FreeCrtcSetConfigs(xf86_crtc_configs, num_configs); - - /* - * The driver is allowed to answer with one of three - * responses: - */ - switch (response) { - case xf86SetConfigFailed: - - /* The configuration isn't usable, or some error - * occurred while setting it. Everything has been - * cleaned up and we're ready to return an error - * back to the client - */ - return FALSE; - case xf86SetConfigDone: - - /* The configuration was acceptable, and the whole - * mode setting experience is over. Nothing more to do - * here. - */ - return TRUE; - case xf86SetConfigChecked: - - /* The configuration was acceptable, but the driver - * didn't actually do anything. Go ask the DIX code - * to do the mode setting operation using the simpler - * interfaces - */ - break; - } - } - return miRRSetCrtcConfigs(screen, screen_config, crtc_configs, num_configs); -} - -static Bool -xf86RandR12EnterVT (int screen_index, int flags) -{ - ScreenPtr pScreen = screenInfo.screens[screen_index]; - ScrnInfoPtr pScrn = xf86Screens[screen_index]; - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - rrScrPrivPtr rp = rrGetScrPriv(pScreen); - Bool ret; - int i; - - if (randrp->orig_EnterVT) { - pScrn->EnterVT = randrp->orig_EnterVT; - ret = pScrn->EnterVT (screen_index, flags); - randrp->orig_EnterVT = pScrn->EnterVT; - pScrn->EnterVT = xf86RandR12EnterVT; - if (!ret) - return FALSE; - } - - /* reload gamma */ - for (i = 0; i < rp->numCrtcs; i++) - xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]); - - return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */ -} - -static Bool -xf86RandR12Init12 (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - rrScrPrivPtr rp = rrGetScrPriv(pScreen); - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - int i; - - rp->rrGetInfo = xf86RandR12GetInfo12; - rp->rrScreenSetSize = xf86RandR12ScreenSetSize; - rp->rrCrtcSet = xf86RandR12CrtcSet; - rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma; - rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma; - rp->rrOutputSetProperty = xf86RandR12OutputSetProperty; - rp->rrOutputValidateMode = xf86RandR12OutputValidateMode; - rp->rrOutputGetProperty = xf86RandR13OutputGetProperty; - rp->rrGetPanning = xf86RandR13GetPanning; - rp->rrSetPanning = xf86RandR13SetPanning; - rp->rrModeDestroy = xf86RandR12ModeDestroy; - rp->rrSetConfig = NULL; - pScrn->PointerMoved = xf86RandR12PointerMoved; - pScrn->ChangeGamma = xf86RandR12ChangeGamma; - rp->rrSetCrtcSpriteTransform = xf86RandR14SetCrtcSpriteTransform; - rp->rrSetCrtcConfigs = xf86RRSetCrtcConfigs; - rp->rrQueryScanoutPixmaps = xf86RRQueryScanoutPixmaps; - rp->rrCreateScanoutPixmap = xf86RRCreateScanoutPixmap; - - randrp->orig_EnterVT = pScrn->EnterVT; - pScrn->EnterVT = xf86RandR12EnterVT; - - if (!xf86RandR12CreateObjects12 (pScreen)) - return FALSE; - - /* - * Configure output modes - */ - if (!xf86RandR12SetInfo12 (pScreen)) - return FALSE; - for (i = 0; i < rp->numCrtcs; i++) { - xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]); - } - return TRUE; -} - -#endif - -Bool -xf86RandR12PreInit (ScrnInfoPtr pScrn) -{ - return TRUE; -} +/* + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#else +#ifdef HAVE_CONFIG_H +#include +#endif +#endif + +#include "xf86.h" +#include "os.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include "inputstr.h" +#include +#include + +#include "xf86Crtc.h" +#include "xf86RandR12.h" + +typedef struct _xf86RandR12Info { + int virtualX; + int virtualY; + int mmWidth; + int mmHeight; + int maxX; + int maxY; + int pointerX; + int pointerY; + Rotation rotation; /* current mode */ + Rotation supported_rotations; /* driver supported */ + + /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends + * (actually, any time that we switch back into our VT). + * + * See https://bugs.freedesktop.org/show_bug.cgi?id=21554 + */ + xf86EnterVTProc *orig_EnterVT; +} XF86RandRInfoRec, *XF86RandRInfoPtr; + +#ifdef RANDR_12_INTERFACE +static Bool xf86RandR12Init12 (ScreenPtr pScreen); +static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen); +#endif + +static int xf86RandR12Generation; + +static DevPrivateKeyRec xf86RandR12KeyRec; +static DevPrivateKey xf86RandR12Key; +#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ + dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key)) + + +static int +xf86RandR12ModeRefresh (DisplayModePtr mode) +{ + if (mode->VRefresh) + return (int) (mode->VRefresh + 0.5); + else + return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5); +} + +/* Adapt panning area; return TRUE if panning area was valid without adaption */ +static int +xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight) +{ + int ret = TRUE; + + if (crtc->version < 2) + return FALSE; + + if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) { + /* Panning in X is disabled */ + if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2) + /* Illegal configuration -> fail/disable */ + ret = FALSE; + crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0; + crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0; + crtc->panningBorder[0] = crtc->panningBorder[2] = 0; + } else { + /* Panning in X is enabled */ + if (crtc->panningTotalArea.x1 < 0) { + /* Panning region outside screen -> move inside */ + crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1; + crtc->panningTotalArea.x1 = 0; + ret = FALSE; + } + if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) { + /* Panning region smaller than displayed area -> crop to displayed area */ + crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay; + ret = FALSE; + } + if (crtc->panningTotalArea.x2 > screenWidth) { + /* Panning region larger than screen -> move inside, then crop to screen */ + crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth; + crtc->panningTotalArea.x2 = screenWidth; + ret = FALSE; + if (crtc->panningTotalArea.x1 < 0) + crtc->panningTotalArea.x1 = 0; + } + if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) { + /* Borders too large -> set to 0 */ + crtc->panningBorder[0] = crtc->panningBorder[2] = 0; + ret = FALSE; + } + } + + if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) { + /* Panning in Y is disabled */ + if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2) + /* Illegal configuration -> fail/disable */ + ret = FALSE; + crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0; + crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0; + crtc->panningBorder[1] = crtc->panningBorder[3] = 0; + } else { + /* Panning in Y is enabled */ + if (crtc->panningTotalArea.y1 < 0) { + /* Panning region outside screen -> move inside */ + crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1; + crtc->panningTotalArea.y1 = 0; + ret = FALSE; + } + if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) { + /* Panning region smaller than displayed area -> crop to displayed area */ + crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay; + ret = FALSE; + } + if (crtc->panningTotalArea.y2 > screenHeight) { + /* Panning region larger than screen -> move inside, then crop to screen */ + crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight; + crtc->panningTotalArea.y2 = screenHeight; + ret = FALSE; + if (crtc->panningTotalArea.y1 < 0) + crtc->panningTotalArea.y1 = 0; + } + if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) { + /* Borders too large -> set to 0 */ + crtc->panningBorder[1] = crtc->panningBorder[3] = 0; + ret = FALSE; + } + } + + return ret; +} + +/* + * The heart of the panning operation: + * + * Given a frame buffer position (fb_x, fb_y), + * and a crtc position (crtc_x, crtc_y), + * and a transform matrix which maps frame buffer to crtc, + * compute a panning position (pan_x, pan_y) that + * makes the resulting transform line those two up + */ + +static void +xf86ComputeCrtcPan (Bool transform_in_use, + struct pixman_f_transform *m, + double screen_x, double screen_y, + double crtc_x, double crtc_y, + int old_pan_x, int old_pan_y, + int *new_pan_x, int *new_pan_y) +{ + if (transform_in_use) { + /* + * Given the current transform, M, the current position + * on the Screen, S, and the desired position on the CRTC, + * C, compute a translation, T, such that: + * + * M T S = C + * + * where T is of the form + * + * | 1 0 dx | + * | 0 1 dy | + * | 0 0 1 | + * + * M T S = + * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F | + * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F | + * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F | + * + * R = M S + * + * Cx F = M00 dx + M01 dy + R0 + * Cy F = M10 dx + M11 dy + R1 + * F = M20 dx + M21 dy + R2 + * + * Zero out dx, then dy + * + * F (Cx M10 - Cy M00) = + * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1 + * F (M10 - Cy M20) = + * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1 + * + * F (Cx M11 - Cy M01) = + * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1 + * F (M11 - Cy M21) = + * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1 + * + * Make some temporaries + * + * T = | Cx M10 - Cy M00 | + * | Cx M11 - Cy M01 | + * + * U = | M10 M01 - M00 M11 | + * | M11 M00 - M01 M10 | + * + * Q = | M10 R0 - M00 R1 | + * | M11 R0 - M01 R1 | + * + * P = | M10 - Cy M20 | + * | M11 - Cy M21 | + * + * W = | M10 M21 - M20 M11 | + * | M11 M20 - M21 M10 | + * + * V = | M10 R2 - M20 R1 | + * | M11 R2 - M21 R1 | + * + * Rewrite: + * + * F T0 = U0 dy + Q0 + * F P0 = W0 dy + V0 + * F T1 = U1 dx + Q1 + * F P1 = W1 dx + V1 + * + * Solve for F (two ways) + * + * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0 + * + * W0 Q0 - U0 V0 + * F = ------------- + * W0 T0 - U0 P0 + * + * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1 + * + * W1 Q1 - U1 V1 + * F = ------------- + * W1 T1 - U1 P1 + * + * We'll use which ever solution works (denominator != 0) + * + * Finally, solve for dx and dy: + * + * dx = (F T1 - Q1) / U1 + * dx = (F P1 - V1) / W1 + * + * dy = (F T0 - Q0) / U0 + * dy = (F P0 - V0) / W0 + */ + double r[3]; + double q[2], u[2], t[2], v[2], w[2], p[2]; + double f; + struct pict_f_vector d; + int i; + + /* Get the un-normalized crtc coordinates again */ + for (i = 0; i < 3; i++) + r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2]; + + /* Combine values into temporaries */ + for (i = 0; i < 2; i++) { + q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1]; + u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i]; + t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y; + + v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1]; + w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i]; + p[i] = m->m[1][i] - m->m[2][i] * crtc_y; + } + + /* Find a way to compute f */ + f = 0; + for (i = 0; i < 2; i++) { + double a = w[i] * q[i] - u[i] * v[i]; + double b = w[i] * t[i] - u[i] * p[i]; + if (b != 0) { + f = a/b; + break; + } + } + + /* Solve for the resulting transform vector */ + for (i = 0; i < 2; i++) { + if (u[i]) + d.v[1-i] = (t[i] * f - q[i]) / u[i]; + else if (w[1]) + d.v[1-i] = (p[i] * f - v[i]) / w[i]; + else + d.v[1-i] = 0; + } + *new_pan_x = old_pan_x - floor (d.v[0] + 0.5); + *new_pan_y = old_pan_y - floor (d.v[1] + 0.5); + } else { + *new_pan_x = screen_x - crtc_x; + *new_pan_y = screen_y - crtc_y; + } +} + +static void +xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y) +{ + int newX, newY; + int width, height; + Bool panned = FALSE; + + if (crtc->version < 2) + return; + + if (! crtc->enabled || + (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 && + crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1)) + return; + + newX = crtc->x; + newY = crtc->y; + width = crtc->mode.HDisplay; + height = crtc->mode.VDisplay; + + if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 || + (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) && + (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 || + (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2))) + { + struct pict_f_vector c; + + /* + * Pre-clip the mouse position to the panning area so that we don't + * push the crtc outside. This doesn't deal with changes to the + * panning values, only mouse position changes. + */ + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) + { + if (x < crtc->panningTotalArea.x1) + x = crtc->panningTotalArea.x1; + if (x >= crtc->panningTotalArea.x2) + x = crtc->panningTotalArea.x2 - 1; + } + if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) + { + if (y < crtc->panningTotalArea.y1) + y = crtc->panningTotalArea.y1; + if (y >= crtc->panningTotalArea.y2) + y = crtc->panningTotalArea.y2 - 1; + } + + c.v[0] = x; + c.v[1] = y; + c.v[2] = 1.0; + if (crtc->transform_in_use) { + pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c); + } else { + c.v[0] -= crtc->x; + c.v[1] -= crtc->y; + } + + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) { + if (c.v[0] < crtc->panningBorder[0]) { + c.v[0] = crtc->panningBorder[0]; + panned = TRUE; + } + if (c.v[0] >= width - crtc->panningBorder[2]) { + c.v[0] = width - crtc->panningBorder[2] - 1; + panned = TRUE; + } + } + if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { + if (c.v[1] < crtc->panningBorder[1]) { + c.v[1] = crtc->panningBorder[1]; + panned = TRUE; + } + if (c.v[1] >= height - crtc->panningBorder[3]) { + c.v[1] = height - crtc->panningBorder[3] - 1; + panned = TRUE; + } + } + if (panned) + xf86ComputeCrtcPan (crtc->transform_in_use, + &crtc->f_framebuffer_to_crtc, + x, y, c.v[0], c.v[1], + newX, newY, &newX, &newY); + } + + /* + * Ensure that the crtc is within the panning region. + * + * XXX This computation only works when we do not have a transform + * in use. + */ + if (!crtc->transform_in_use) + { + /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */ + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) { + if (newX > crtc->panningTotalArea.x2 - width) + newX = crtc->panningTotalArea.x2 - width; + if (newX < crtc->panningTotalArea.x1) + newX = crtc->panningTotalArea.x1; + } + if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { + if (newY > crtc->panningTotalArea.y2 - height) + newY = crtc->panningTotalArea.y2 - height; + if (newY < crtc->panningTotalArea.y1) + newY = crtc->panningTotalArea.y1; + } + } + if (newX != crtc->x || newY != crtc->y) + xf86CrtcSetOrigin (crtc, newX, newY); +} + +static Bool +xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations) +{ + RRScreenSizePtr pSize; + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int refresh0 = 60; + int maxX = 0, maxY = 0; + + *rotations = randrp->supported_rotations; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = scrp->virtualX; + randrp->virtualY = scrp->virtualY; + } + + /* Re-probe the outputs for new monitors or modes */ + if (scrp->vtSema) + { + xf86ProbeOutputModes (scrp, 0, 0); + xf86SetScrnInfoModes (scrp); + } + + for (mode = scrp->modes; ; mode = mode->next) + { + int refresh = xf86RandR12ModeRefresh (mode); + if (randrp->maxX == 0 || randrp->maxY == 0) + { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode == scrp->modes) + refresh0 = refresh; + pSize = RRRegisterSize (pScreen, + mode->HDisplay, mode->VDisplay, + randrp->mmWidth, randrp->mmHeight); + if (!pSize) + return FALSE; + RRRegisterRate (pScreen, pSize, refresh); + + if (xf86ModesEqual(mode, scrp->currentMode)) + { + RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize); + } + if (mode->next == scrp->modes) + break; + } + + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + + return TRUE; +} + +static Bool +xf86RandR12SetMode (ScreenPtr pScreen, + DisplayModePtr mode, + Bool useVirtual, + int mmWidth, + int mmHeight) +{ + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int oldWidth = pScreen->width; + int oldHeight = pScreen->height; + int oldmmWidth = pScreen->mmWidth; + int oldmmHeight = pScreen->mmHeight; + WindowPtr pRoot = pScreen->root; + DisplayModePtr currentMode = NULL; + Bool ret = TRUE; + + if (pRoot) + (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE); + if (useVirtual) + { + scrp->virtualX = randrp->virtualX; + scrp->virtualY = randrp->virtualY; + } + else + { + scrp->virtualX = mode->HDisplay; + scrp->virtualY = mode->VDisplay; + } + + if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270)) + { + /* If the screen is rotated 90 or 270 degrees, swap the sizes. */ + pScreen->width = scrp->virtualY; + pScreen->height = scrp->virtualX; + pScreen->mmWidth = mmHeight; + pScreen->mmHeight = mmWidth; + } + else + { + pScreen->width = scrp->virtualX; + pScreen->height = scrp->virtualY; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + } + if (scrp->currentMode == mode) { + /* Save current mode */ + currentMode = scrp->currentMode; + /* Reset, just so we ensure the drivers SwitchMode is called */ + scrp->currentMode = NULL; + } + /* + * We know that if the driver failed to SwitchMode to the rotated + * version, then it should revert back to it's prior mode. + */ + if (!xf86SwitchMode (pScreen, mode)) + { + ret = FALSE; + scrp->virtualX = pScreen->width = oldWidth; + scrp->virtualY = pScreen->height = oldHeight; + pScreen->mmWidth = oldmmWidth; + pScreen->mmHeight = oldmmHeight; + scrp->currentMode = currentMode; + } + + /* + * Make sure the layout is correct + */ + xf86ReconfigureLayout(); + + /* + * Make sure the whole screen is visible + */ + xf86SetViewport (pScreen, pScreen->width, pScreen->height); + xf86SetViewport (pScreen, 0, 0); + if (pRoot) + (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE); + return ret; +} + +Bool +xf86RandR12SetConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize) +{ + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int px, py; + Bool useVirtual = FALSE; + int maxX = 0, maxY = 0; + Rotation oldRotation = randrp->rotation; + + randrp->rotation = rotation; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = scrp->virtualX; + randrp->virtualY = scrp->virtualY; + } + + miPointerGetPosition (inputInfo.pointer, &px, &py); + for (mode = scrp->modes; ; mode = mode->next) + { + if (randrp->maxX == 0 || randrp->maxY == 0) + { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode->HDisplay == pSize->width && + mode->VDisplay == pSize->height && + (rate == 0 || xf86RandR12ModeRefresh (mode) == rate)) + break; + if (mode->next == scrp->modes) + { + if (pSize->width == randrp->virtualX && + pSize->height == randrp->virtualY) + { + mode = scrp->modes; + useVirtual = TRUE; + break; + } + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + return FALSE; + } + } + + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + + if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth, + pSize->mmHeight)) { + randrp->rotation = oldRotation; + return FALSE; + } + + /* + * Move the cursor back where it belongs; SwitchMode repositions it + */ + if (pScreen == miPointerGetScreen(inputInfo.pointer)) + { + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + xf86SetViewport(pScreen, px, py); + + (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE); + } + + return TRUE; +} + +static Bool +xf86RandR12ScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + WindowPtr pRoot = pScreen->root; + PixmapPtr pScrnPix; + Bool ret = FALSE; + int c; + + if (xf86RandR12Key) { + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = pScrn->virtualX; + randrp->virtualY = pScrn->virtualY; + } + } + if (pRoot && pScrn->vtSema) + (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE); + + /* Let the driver update virtualX and virtualY */ + if (!(*config->funcs->resize)(pScrn, width, height)) + goto finish; + + ret = TRUE; + /* Update panning information */ + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 || + crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { + if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1) + crtc->panningTotalArea.x2 += width - pScreen->width; + if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1) + crtc->panningTotalArea.y2 += height - pScreen->height; + if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1) + crtc->panningTrackingArea.x2 += width - pScreen->width; + if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1) + crtc->panningTrackingArea.y2 += height - pScreen->height; + xf86RandR13VerifyPanningArea (crtc, width, height); + xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); + } + } + + pScrnPix = (*pScreen->GetScreenPixmap)(pScreen); + pScreen->width = pScrnPix->drawable.width = width; + pScreen->height = pScrnPix->drawable.height = height; + randrp->mmWidth = pScreen->mmWidth = mmWidth; + randrp->mmHeight = pScreen->mmHeight = mmHeight; + + xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1); + xf86SetViewport (pScreen, 0, 0); + +finish: + if (pRoot && pScrn->vtSema) + (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); +#if RANDR_12_INTERFACE + if (xf86RandR12Key && pScreen->root && ret) + RRScreenSizeNotify (pScreen); +#endif + return ret; +} + +Rotation +xf86RandR12GetRotation(ScreenPtr pScreen) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + return randrp->rotation; +} + +Bool +xf86RandR12CreateScreenResources (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config; + XF86RandRInfoPtr randrp; + int c; + int width, height; + int mmWidth, mmHeight; +#ifdef PANORAMIX + /* XXX disable RandR when using Xinerama */ + if (!noPanoramiXExtension) + return TRUE; +#endif + + config = XF86_CRTC_CONFIG_PTR(pScrn); + randrp = XF86RANDRINFO(pScreen); + /* + * Compute size of screen + */ + width = 0; height = 0; + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation); + int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation); + + if (crtc->enabled) { + if (crtc_width > width) + width = crtc_width; + if (crtc_height > height) + height = crtc_height; + if (crtc->panningTotalArea.x2 > width) + width = crtc->panningTotalArea.x2; + if (crtc->panningTotalArea.y2 > height) + height = crtc->panningTotalArea.y2; + } + } + + if (width && height) + { + /* + * Compute physical size of screen + */ + if (monitorResolution) + { + mmWidth = width * 25.4 / monitorResolution; + mmHeight = height * 25.4 / monitorResolution; + } + else + { + xf86OutputPtr output = xf86CompatOutput(pScrn); + + if (output && + output->conf_monitor && + (output->conf_monitor->mon_width > 0 && + output->conf_monitor->mon_height > 0)) + { + /* + * Prefer user configured DisplaySize + */ + mmWidth = output->conf_monitor->mon_width; + mmHeight = output->conf_monitor->mon_height; + } + else + { + /* + * Otherwise, just set the screen to DEFAULT_DPI + */ + mmWidth = width * 25.4 / DEFAULT_DPI; + mmHeight = height * 25.4 / DEFAULT_DPI; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting screen physical size to %d x %d\n", + mmWidth, mmHeight); + /* + * This is the initial setting of the screen size. + * We have to pre-set it here, otherwise panning would be adapted + * to the new screen size. + */ + pScreen->width = width; + pScreen->height = height; + xf86RandR12ScreenSetSize (pScreen, + width, + height, + mmWidth, + mmHeight); + } + + if (xf86RandR12Key == NULL) + return TRUE; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = pScrn->virtualX; + randrp->virtualY = pScrn->virtualY; + } + xf86CrtcSetScreenSubpixelOrder (pScreen); +#if RANDR_12_INTERFACE + if (xf86RandR12CreateScreenResources12 (pScreen)) + return TRUE; +#endif + return TRUE; +} + + +Bool +xf86RandR12Init (ScreenPtr pScreen) +{ + rrScrPrivPtr rp; + XF86RandRInfoPtr randrp; + +#ifdef PANORAMIX + /* XXX disable RandR when using Xinerama */ + if (!noPanoramiXExtension) + { + if (xf86NumScreens == 1) + noPanoramiXExtension = TRUE; + else + return TRUE; + } +#endif + + if (xf86RandR12Generation != serverGeneration) + xf86RandR12Generation = serverGeneration; + + xf86RandR12Key = &xf86RandR12KeyRec; + if (!dixRegisterPrivateKey(&xf86RandR12KeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + randrp = malloc(sizeof (XF86RandRInfoRec)); + if (!randrp) + return FALSE; + + if (!RRScreenInit(pScreen)) + { + free(randrp); + return FALSE; + } + rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = xf86RandR12GetInfo; + rp->rrSetConfig = xf86RandR12SetConfig; + + randrp->virtualX = -1; + randrp->virtualY = -1; + randrp->mmWidth = pScreen->mmWidth; + randrp->mmHeight = pScreen->mmHeight; + + randrp->rotation = RR_Rotate_0; /* initial rotated mode */ + + randrp->supported_rotations = RR_Rotate_0; + + randrp->maxX = randrp->maxY = 0; + + dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp); + +#if RANDR_12_INTERFACE + if (!xf86RandR12Init12 (pScreen)) + return FALSE; +#endif + return TRUE; +} + +void +xf86RandR12CloseScreen (ScreenPtr pScreen) +{ + XF86RandRInfoPtr randrp; + + if (xf86RandR12Key == NULL) + return; + + randrp = XF86RANDRINFO(pScreen); +#if RANDR_12_INTERFACE + xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT; +#endif + + free(randrp); +} + +void +xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) +{ + XF86RandRInfoPtr randrp; +#if RANDR_12_INTERFACE + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int c; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +#endif + + if (xf86RandR12Key == NULL) + return; + + randrp = XF86RANDRINFO(pScreen); +#if RANDR_12_INTERFACE + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + + RRCrtcSetRotations (crtc->randr_crtc, rotations); + } +#endif + randrp->supported_rotations = rotations; +} + +void +xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms) +{ + XF86RandRInfoPtr randrp; +#if RANDR_13_INTERFACE + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int c; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +#endif + + if (xf86RandR12Key == NULL) + return; + + randrp = XF86RANDRINFO(pScreen); +#if RANDR_13_INTERFACE + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + + RRCrtcSetTransformSupport (crtc->randr_crtc, transforms); + } +#endif +} + +void +xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y) +{ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + + if (xf86RandR12Generation != serverGeneration || + XF86RANDRINFO(pScreen)->virtualX == -1) + { + *x = pScrn->virtualX; + *y = pScrn->virtualY; + } else { + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + *x = randrp->virtualX; + *y = randrp->virtualY; + } +} + +#if RANDR_12_INTERFACE + +#define FLAG_BITS (RR_HSyncPositive | \ + RR_HSyncNegative | \ + RR_VSyncPositive | \ + RR_VSyncNegative | \ + RR_Interlace | \ + RR_DoubleScan | \ + RR_CSync | \ + RR_CSyncPositive | \ + RR_CSyncNegative | \ + RR_HSkewPresent | \ + RR_BCast | \ + RR_PixelMultiplex | \ + RR_DoubleClock | \ + RR_ClockDivideBy2) + +static Bool +xf86RandRModeMatches (RRModePtr randr_mode, + DisplayModePtr mode) +{ +#if 0 + if (match_name) + { + /* check for same name */ + int len = strlen (mode->name); + if (randr_mode->mode.nameLength != len) return FALSE; + if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE; + } +#endif + + /* check for same timings */ + if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE; + if (randr_mode->mode.width != mode->HDisplay) return FALSE; + if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE; + if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE; + if (randr_mode->mode.hTotal != mode->HTotal) return FALSE; + if (randr_mode->mode.hSkew != mode->HSkew) return FALSE; + if (randr_mode->mode.height != mode->VDisplay) return FALSE; + if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE; + if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE; + if (randr_mode->mode.vTotal != mode->VTotal) return FALSE; + + /* check for same flags (using only the XF86 valid flag bits) */ + if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS)) + return FALSE; + + /* everything matches */ + return TRUE; +} + +static Bool +xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) +{ + ScreenPtr pScreen = randr_crtc->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + RRModePtr randr_mode = NULL; + int x; + int y; + Rotation rotation; + int numOutputs; + RROutputPtr *randr_outputs; + RROutputPtr randr_output; + xf86CrtcPtr crtc = randr_crtc->devPrivate; + xf86OutputPtr output; + int i, j; + DisplayModePtr mode = &crtc->mode; + Bool ret; + + randr_outputs = malloc(config->num_output * sizeof (RROutputPtr)); + if (!randr_outputs) + return FALSE; + x = crtc->x; + y = crtc->y; + rotation = crtc->rotation; + numOutputs = 0; + randr_mode = NULL; + for (i = 0; i < config->num_output; i++) + { + output = config->output[i]; + if (output->crtc == crtc) + { + randr_output = output->randr_output; + randr_outputs[numOutputs++] = randr_output; + /* + * We make copies of modes, so pointer equality + * isn't sufficient + */ + for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++) + { + RRModePtr m = (j < randr_output->numModes ? + randr_output->modes[j] : + randr_output->userModes[j-randr_output->numModes]); + + if (xf86RandRModeMatches (m, mode)) + { + randr_mode = m; + break; + } + } + } + } + ret = RRCrtcNotify (randr_crtc, randr_mode, x, y, + rotation, + crtc->transformPresent ? &crtc->transform : NULL, + numOutputs, randr_outputs); + free(randr_outputs); + return ret; +} + +/* + * Convert a RandR mode to a DisplayMode + */ +static void +xf86RandRModeConvert (ScrnInfoPtr scrn, + RRModePtr randr_mode, + DisplayModePtr mode) +{ + memset(mode, 0, sizeof(DisplayModeRec)); + mode->status = MODE_OK; + + mode->Clock = randr_mode->mode.dotClock / 1000; + + mode->HDisplay = randr_mode->mode.width; + mode->HSyncStart = randr_mode->mode.hSyncStart; + mode->HSyncEnd = randr_mode->mode.hSyncEnd; + mode->HTotal = randr_mode->mode.hTotal; + mode->HSkew = randr_mode->mode.hSkew; + + mode->VDisplay = randr_mode->mode.height; + mode->VSyncStart = randr_mode->mode.vSyncStart; + mode->VSyncEnd = randr_mode->mode.vSyncEnd; + mode->VTotal = randr_mode->mode.vTotal; + mode->VScan = 0; + + mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS; + + xf86SetModeCrtc (mode, scrn->adjustFlags); +} + +static Bool +xf86RandR12CrtcSet (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + RRModePtr randr_mode, + int x, + int y, + Rotation rotation, + int num_randr_outputs, + RROutputPtr *randr_outputs) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc = randr_crtc->devPrivate; + RRTransformPtr transform; + Bool changed = FALSE; + int o, ro; + xf86CrtcPtr *save_crtcs; + Bool save_enabled = crtc->enabled; + + if (!crtc->scrn->vtSema) + return FALSE; + + save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr)); + if ((randr_mode != NULL) != crtc->enabled) + changed = TRUE; + else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode)) + changed = TRUE; + + if (rotation != crtc->rotation) + changed = TRUE; + + transform = RRCrtcGetTransform (randr_crtc); + if ((transform != NULL) != crtc->transformPresent) + changed = TRUE; + else if (transform && memcmp (&transform->transform, &crtc->transform.transform, + sizeof (transform->transform)) != 0) + changed = TRUE; + + if (x != crtc->x || y != crtc->y) + changed = TRUE; + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + xf86CrtcPtr new_crtc; + + save_crtcs[o] = output->crtc; + + if (output->crtc == crtc) + new_crtc = NULL; + else + new_crtc = output->crtc; + for (ro = 0; ro < num_randr_outputs; ro++) + if (output->randr_output == randr_outputs[ro]) + { + new_crtc = crtc; + break; + } + if (new_crtc != output->crtc) + { + changed = TRUE; + output->crtc = new_crtc; + } + } + for (ro = 0; ro < num_randr_outputs; ro++) + if (randr_outputs[ro]->pendingProperties) + changed = TRUE; + + /* XXX need device-independent mode setting code through an API */ + if (changed) + { + crtc->enabled = randr_mode != NULL; + + if (randr_mode) + { + DisplayModeRec mode; + RRTransformPtr transform = RRCrtcGetTransform (randr_crtc); + + xf86RandRModeConvert (pScrn, randr_mode, &mode); + if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y)) + { + crtc->enabled = save_enabled; + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + output->crtc = save_crtcs[o]; + } + free(save_crtcs); + return FALSE; + } + xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height); + xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); + /* + * Save the last successful setting for EnterVT + */ + crtc->desiredMode = mode; + crtc->desiredRotation = rotation; + if (transform) { + crtc->desiredTransform = *transform; + crtc->desiredTransformPresent = TRUE; + } else + crtc->desiredTransformPresent = FALSE; + + crtc->desiredX = x; + crtc->desiredY = y; + } + xf86DisableUnusedFunctions (pScrn); + } + free(save_crtcs); + return xf86RandR12CrtcNotify (randr_crtc); +} + +static Bool +xf86RandR12CrtcSetGamma (ScreenPtr pScreen, + RRCrtcPtr randr_crtc) +{ + xf86CrtcPtr crtc = randr_crtc->devPrivate; + + if (crtc->funcs->gamma_set == NULL) + return FALSE; + + if (!crtc->scrn->vtSema) + return TRUE; + + /* Realloc local gamma if needed. */ + if (randr_crtc->gammaSize != crtc->gamma_size) { + CARD16 *tmp_ptr; + tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16)); + if (!tmp_ptr) + return FALSE; + crtc->gamma_red = tmp_ptr; + crtc->gamma_green = crtc->gamma_red + crtc->gamma_size; + crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size; + } + + crtc->gamma_size = randr_crtc->gammaSize; + memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16)); + memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16)); + memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16)); + + /* Only set it when the crtc is actually running. + * Otherwise it will be set when it's activated. + */ + if (crtc->active) + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); + + return TRUE; +} + +static Bool +xf86RandR12CrtcGetGamma (ScreenPtr pScreen, + RRCrtcPtr randr_crtc) +{ + xf86CrtcPtr crtc = randr_crtc->devPrivate; + + if (!crtc->gamma_size) + return FALSE; + + if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue) + return FALSE; + + /* Realloc randr gamma if needed. */ + if (randr_crtc->gammaSize != crtc->gamma_size) { + CARD16 *tmp_ptr; + tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16)); + if (!tmp_ptr) + return FALSE; + randr_crtc->gammaRed = tmp_ptr; + randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size; + randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size; + } + randr_crtc->gammaSize = crtc->gamma_size; + memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16)); + memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16)); + memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16)); + + return TRUE; +} + +static Bool +xf86RandR12OutputSetProperty (ScreenPtr pScreen, + RROutputPtr randr_output, + Atom property, + RRPropertyValuePtr value) +{ + xf86OutputPtr output = randr_output->devPrivate; + + /* If we don't have any property handler, then we don't care what the + * user is setting properties to. + */ + if (output->funcs->set_property == NULL) + return TRUE; + + /* + * This function gets called even when vtSema is FALSE, as + * drivers will need to remember the correct value to apply + * when the VT switch occurs + */ + return output->funcs->set_property(output, property, value); +} + +static Bool +xf86RandR13OutputGetProperty (ScreenPtr pScreen, + RROutputPtr randr_output, + Atom property) +{ + xf86OutputPtr output = randr_output->devPrivate; + + if (output->funcs->get_property == NULL) + return TRUE; + + /* Should be safe even w/o vtSema */ + return output->funcs->get_property(output, property); +} + +static Bool +xf86RandR12OutputValidateMode (ScreenPtr pScreen, + RROutputPtr randr_output, + RRModePtr randr_mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86OutputPtr output = randr_output->devPrivate; + DisplayModeRec mode; + + xf86RandRModeConvert (pScrn, randr_mode, &mode); + /* + * This function may be called when vtSema is FALSE, so + * the underlying function must either avoid touching the hardware + * or return FALSE when vtSema is FALSE + */ + if (output->funcs->mode_valid (output, &mode) != MODE_OK) + return FALSE; + return TRUE; +} + +static void +xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode) +{ +} + +/** + * Given a list of xf86 modes and a RandR Output object, construct + * RandR modes and assign them to the output + */ +static Bool +xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes) +{ + DisplayModePtr mode; + RRModePtr *rrmodes = NULL; + int nmode = 0; + int npreferred = 0; + Bool ret = TRUE; + int pref; + + for (mode = modes; mode; mode = mode->next) + nmode++; + + if (nmode) { + rrmodes = malloc(nmode * sizeof (RRModePtr)); + + if (!rrmodes) + return FALSE; + nmode = 0; + + for (pref = 1; pref >= 0; pref--) { + for (mode = modes; mode; mode = mode->next) { + if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) { + xRRModeInfo modeInfo; + RRModePtr rrmode; + + modeInfo.nameLength = strlen (mode->name); + modeInfo.width = mode->HDisplay; + modeInfo.dotClock = mode->Clock * 1000; + modeInfo.hSyncStart = mode->HSyncStart; + modeInfo.hSyncEnd = mode->HSyncEnd; + modeInfo.hTotal = mode->HTotal; + modeInfo.hSkew = mode->HSkew; + + modeInfo.height = mode->VDisplay; + modeInfo.vSyncStart = mode->VSyncStart; + modeInfo.vSyncEnd = mode->VSyncEnd; + modeInfo.vTotal = mode->VTotal; + modeInfo.modeFlags = mode->Flags; + + rrmode = RRModeGet (&modeInfo, mode->name); + if (rrmode) { + rrmodes[nmode++] = rrmode; + npreferred += pref; + } + } + } + } + } + + ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred); + free(rrmodes); + return ret; +} + +/* + * Mirror the current mode configuration to RandR + */ +static Bool +xf86RandR12SetInfo12 (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + RROutputPtr *clones; + RRCrtcPtr *crtcs; + int ncrtc; + int o, c, l; + RRCrtcPtr randr_crtc; + int nclone; + + clones = malloc(config->num_output * sizeof (RROutputPtr)); + crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr)); + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + ncrtc = 0; + for (c = 0; c < config->num_crtc; c++) + if (output->possible_crtcs & (1 << c)) + crtcs[ncrtc++] = config->crtc[c]->randr_crtc; + + if (output->crtc) + randr_crtc = output->crtc->randr_crtc; + else + randr_crtc = NULL; + + if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc)) + { + free(crtcs); + free(clones); + return FALSE; + } + + RROutputSetPhysicalSize(output->randr_output, + output->mm_width, + output->mm_height); + xf86RROutputSetModes (output->randr_output, output->probed_modes); + + switch (output->status) { + case XF86OutputStatusConnected: + RROutputSetConnection (output->randr_output, RR_Connected); + break; + case XF86OutputStatusDisconnected: + RROutputSetConnection (output->randr_output, RR_Disconnected); + break; + case XF86OutputStatusUnknown: + RROutputSetConnection (output->randr_output, RR_UnknownConnection); + break; + } + + RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order); + + /* + * Valid clones + */ + nclone = 0; + for (l = 0; l < config->num_output; l++) + { + xf86OutputPtr clone = config->output[l]; + + if (l != o && (output->possible_clones & (1 << l))) + clones[nclone++] = clone->randr_output; + } + if (!RROutputSetClones (output->randr_output, clones, nclone)) + { + free(crtcs); + free(clones); + return FALSE; + } + } + free(crtcs); + free(clones); + return TRUE; +} + + + +/* + * Query the hardware for the current state, then mirror + * that to RandR + */ +static Bool +xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (!pScrn->vtSema) + return TRUE; + xf86ProbeOutputModes (pScrn, 0, 0); + xf86SetScrnInfoModes (pScrn); + return xf86RandR12SetInfo12 (pScreen); +} + +static Bool +xf86RandR12CreateObjects12 (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + int o; + + if (!RRInit ()) + return FALSE; + + /* + * Configure crtcs + */ + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + + crtc->randr_crtc = RRCrtcCreate (pScreen, crtc); + RRCrtcGammaSetSize (crtc->randr_crtc, 256); + } + /* + * Configure outputs + */ + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->randr_output = RROutputCreate (pScreen, output->name, + strlen (output->name), + output); + + if (output->funcs->create_resources != NULL) + output->funcs->create_resources(output); + RRPostPendingProperties (output->randr_output); + } + return TRUE; +} + +static Bool +xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) +{ + int c; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + + if (xf86RandR12Key == NULL) + return TRUE; + + for (c = 0; c < config->num_crtc; c++) + xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); + + RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight, + config->maxWidth, config->maxHeight); + return TRUE; +} + +/* + * Something happened within the screen configuration due + * to DGA, VidMode or hot key. Tell RandR + */ + +void +xf86RandR12TellChanged (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + if (xf86RandR12Key == NULL) + return; + + xf86RandR12SetInfo12 (pScreen); + for (c = 0; c < config->num_crtc; c++) + xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); + + RRTellChanged (pScreen); +} + +static void +xf86RandR12PointerMoved (int scrnIndex, int x, int y) +{ + ScreenPtr pScreen = screenInfo.screens[scrnIndex]; + ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int c; + + randrp->pointerX = x; + randrp->pointerY = y; + for (c = 0; c < config->num_crtc; c++) + xf86RandR13Pan (config->crtc[c], x, y); +} + +static Bool +xf86RandR13GetPanning (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + BoxPtr totalArea, + BoxPtr trackingArea, + INT16 *border) +{ + xf86CrtcPtr crtc = randr_crtc->devPrivate; + + if (crtc->version < 2) + return FALSE; + if (totalArea) + memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec)); + if (trackingArea) + memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec)); + if (border) + memcpy (border, crtc->panningBorder, 4*sizeof(INT16)); + + return TRUE; +} + +static Bool +xf86RandR13SetPanning (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + BoxPtr totalArea, + BoxPtr trackingArea, + INT16 *border) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + xf86CrtcPtr crtc = randr_crtc->devPrivate; + BoxRec oldTotalArea; + BoxRec oldTrackingArea; + INT16 oldBorder[4]; + + + if (crtc->version < 2) + return FALSE; + + memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec)); + memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec)); + memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16)); + + if (totalArea) + memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec)); + if (trackingArea) + memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec)); + if (border) + memcpy (crtc->panningBorder, border, 4*sizeof(INT16)); + + if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) { + xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); + return TRUE; + } else { + /* Restore old settings */ + memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec)); + memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec)); + memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16)); + return FALSE; + } +} + +/* + * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers + * any per-crtc setup. You asked for it... + */ + +static void +gamma_to_ramp(float gamma, CARD16 *ramp, int size) +{ + int i; + + for (i = 0; i < size; i++) { + if (gamma == 1.0) + ramp[i] = i << 8; + else + ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma) + * (double)(size - 1) * 256); + } +} + +static int +xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma) +{ + CARD16 *points, *red, *green, *blue; + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn); + int size; + + if (!crtc) + return Success; + + size = max(0, crtc->gammaSize); + if (!size) + return Success; + + points = calloc(size, 3 * sizeof(CARD16)); + if (!points) + return BadAlloc; + + red = points; + green = points + size; + blue = points + 2 * size; + + gamma_to_ramp(gamma.red, red, size); + gamma_to_ramp(gamma.green, green, size); + gamma_to_ramp(gamma.blue, blue, size); + RRCrtcGammaSet(crtc, red, green, blue); + + free(points); + + pScrn->gamma = gamma; + + return Success; +} + +static Bool +xf86RandR12EnterVT (int screen_index, int flags) +{ + ScreenPtr pScreen = screenInfo.screens[screen_index]; + ScrnInfoPtr pScrn = xf86Screens[screen_index]; + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + Bool ret; + + if (randrp->orig_EnterVT) { + pScrn->EnterVT = randrp->orig_EnterVT; + ret = pScrn->EnterVT (screen_index, flags); + randrp->orig_EnterVT = pScrn->EnterVT; + pScrn->EnterVT = xf86RandR12EnterVT; + if (!ret) + return FALSE; + } + + /* reload gamma */ + int i; + for (i = 0; i < rp->numCrtcs; i++) + xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]); + + return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */ +} + +static Bool +xf86RandR12Init12 (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int i; + + rp->rrGetInfo = xf86RandR12GetInfo12; + rp->rrScreenSetSize = xf86RandR12ScreenSetSize; + rp->rrCrtcSet = xf86RandR12CrtcSet; + rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma; + rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma; + rp->rrOutputSetProperty = xf86RandR12OutputSetProperty; + rp->rrOutputValidateMode = xf86RandR12OutputValidateMode; +#if RANDR_13_INTERFACE + rp->rrOutputGetProperty = xf86RandR13OutputGetProperty; + rp->rrGetPanning = xf86RandR13GetPanning; + rp->rrSetPanning = xf86RandR13SetPanning; +#endif + rp->rrModeDestroy = xf86RandR12ModeDestroy; + rp->rrSetConfig = NULL; + pScrn->PointerMoved = xf86RandR12PointerMoved; + pScrn->ChangeGamma = xf86RandR12ChangeGamma; + + randrp->orig_EnterVT = pScrn->EnterVT; + pScrn->EnterVT = xf86RandR12EnterVT; + + if (!xf86RandR12CreateObjects12 (pScreen)) + return FALSE; + + /* + * Configure output modes + */ + if (!xf86RandR12SetInfo12 (pScreen)) + return FALSE; + for (i = 0; i < rp->numCrtcs; i++) { + xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]); + } + return TRUE; +} + +#endif + +Bool +xf86RandR12PreInit (ScrnInfoPtr pScrn) +{ + return TRUE; +} diff --git a/xorg-server/hw/xfree86/modes/xf86Rotate.c b/xorg-server/hw/xfree86/modes/xf86Rotate.c index 0181bc381..57c3499ac 100644 --- a/xorg-server/hw/xfree86/modes/xf86Rotate.c +++ b/xorg-server/hw/xfree86/modes/xf86Rotate.c @@ -1,565 +1,525 @@ -/* - * Copyright © 2006 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#else -#ifdef HAVE_CONFIG_H -#include -#endif -#endif - -#include -#include -#include - -#include "xf86.h" -#include "xf86DDC.h" -#include "fb.h" -#include "windowstr.h" -#include "xf86Crtc.h" -#include "xf86Modes.h" -#include "xf86RandR12.h" -#include "X11/extensions/render.h" -#include "X11/extensions/dpmsconst.h" -#include "X11/Xatom.h" - -/* borrowed from composite extension, move to Render and publish? */ - -static VisualPtr -compGetWindowVisual (WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - VisualID vid = wVisual (pWin); - int i; - - for (i = 0; i < pScreen->numVisuals; i++) - if (pScreen->visuals[i].vid == vid) - return &pScreen->visuals[i]; - return 0; -} - -static PictFormatPtr -compWindowFormat (WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - - return PictureMatchVisual (pScreen, pWin->drawable.depth, - compGetWindowVisual (pWin)); -} - -#define F(x) IntToxFixed(x) - -#define toF(x) ((float) (x) / 65536.0f) - -static void -xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) -{ - ScrnInfoPtr scrn = crtc->scrn; - ScreenPtr screen = scrn->pScreen; - WindowPtr root = screen->root; - PixmapPtr dst_pixmap = crtc->rotatedPixmap; - PictFormatPtr format = compWindowFormat (screen->root); - int error; - PicturePtr src, dst; - int n = RegionNumRects(region); - BoxPtr b = RegionRects(region); - XID include_inferiors = IncludeInferiors; - - src = CreatePicture (None, - &root->drawable, - format, - CPSubwindowMode, - &include_inferiors, - serverClient, - &error); - if (!src) - return; - - dst = CreatePicture (None, - &dst_pixmap->drawable, - format, - 0L, - NULL, - serverClient, - &error); - if (!dst) - return; - - error = SetPictureTransform (src, &crtc->crtc_to_framebuffer); - if (error) - return; - if (crtc->transform_in_use && crtc->filter) - SetPicturePictFilter (src, crtc->filter, - crtc->params, crtc->nparams); - - if (crtc->shadowClear) - { - CompositePicture (PictOpSrc, - src, NULL, dst, - 0, 0, 0, 0, 0, 0, - crtc->mode.HDisplay, crtc->mode.VDisplay); - crtc->shadowClear = FALSE; - } - else - { - while (n--) - { - BoxRec dst_box; - - dst_box = *b; - dst_box.x1 -= crtc->filter_width >> 1; - dst_box.x2 += crtc->filter_width >> 1; - dst_box.y1 -= crtc->filter_height >> 1; - dst_box.y2 += crtc->filter_height >> 1; - pixman_f_transform_bounds (&crtc->f_framebuffer_to_crtc, &dst_box); - CompositePicture (PictOpSrc, - src, NULL, dst, - dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1, - dst_box.x2 - dst_box.x1, - dst_box.y2 - dst_box.y1); - b++; - } - } - FreePicture (src, None); - FreePicture (dst, None); -} - -static void -xf86CrtcDamageShadow (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - BoxRec damage_box; - RegionRec damage_region; - ScreenPtr pScreen = pScrn->pScreen; - - damage_box.x1 = 0; - damage_box.x2 = crtc->mode.HDisplay; - damage_box.y1 = 0; - damage_box.y2 = crtc->mode.VDisplay; - if (!pixman_transform_bounds (&crtc->crtc_to_framebuffer, &damage_box)) - { - damage_box.x1 = 0; - damage_box.y1 = 0; - damage_box.x2 = pScreen->width; - damage_box.y2 = pScreen->height; - } - if (damage_box.x1 < 0) damage_box.x1 = 0; - if (damage_box.y1 < 0) damage_box.y1 = 0; - if (damage_box.x2 > pScreen->width) damage_box.x2 = pScreen->width; - if (damage_box.y2 > pScreen->height) damage_box.y2 = pScreen->height; - RegionInit(&damage_region, &damage_box, 1); - DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, - &damage_region); - RegionUninit(&damage_region); - crtc->shadowClear = TRUE; -} - -static void -xf86RotatePrepare (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->rotatedData && !crtc->rotatedPixmap) - { - crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, - crtc->rotatedData, - crtc->mode.HDisplay, - crtc->mode.VDisplay); - if (!xf86_config->rotation_damage_registered) - { - /* Hook damage to screen pixmap */ - DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, - xf86_config->rotation_damage); - xf86_config->rotation_damage_registered = TRUE; - EnableLimitedSchedulingLatency(); - } - - xf86CrtcDamageShadow (crtc); - } - } -} - -static Bool -xf86RotateRedisplay(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - DamagePtr damage = xf86_config->rotation_damage; - RegionPtr region; - - if (!damage) - return FALSE; - xf86RotatePrepare (pScreen); - region = DamageRegion(damage); - if (RegionNotEmpty(region)) - { - int c; - SourceValidateProcPtr SourceValidate; - - /* - * SourceValidate is used by the software cursor code - * to pull the cursor off of the screen when reading - * bits from the frame buffer. Bypassing this function - * leaves the software cursor in place - */ - SourceValidate = pScreen->SourceValidate; - pScreen->SourceValidate = NULL; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->transform_in_use && crtc->enabled) - { - RegionRec crtc_damage; - - /* compute portion of damage that overlaps crtc */ - RegionInit(&crtc_damage, &crtc->bounds, 1); - RegionIntersect(&crtc_damage, &crtc_damage, region); - - /* update damaged region */ - if (RegionNotEmpty(&crtc_damage)) - xf86RotateCrtcRedisplay (crtc, &crtc_damage); - - RegionUninit(&crtc_damage); - } - } - pScreen->SourceValidate = SourceValidate; - DamageEmpty(damage); - } - return TRUE; -} - -static void -xf86RotateBlockHandler(int screenNum, pointer blockData, - pointer pTimeout, pointer pReadmask) -{ - ScreenPtr pScreen = screenInfo.screens[screenNum]; - ScrnInfoPtr pScrn = xf86Screens[screenNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - Bool rotation_active; - - rotation_active = xf86RotateRedisplay(pScreen); - pScreen->BlockHandler = xf86_config->BlockHandler; - (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); - /* cannot avoid re-wrapping until all wrapping is audited */ - xf86_config->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = xf86RotateBlockHandler; -} - -void -xf86RotateDestroy (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - ScreenPtr pScreen = pScrn->pScreen; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - - /* Free memory from rotation */ - if (crtc->rotatedPixmap || crtc->rotatedData) - { - crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData); - crtc->rotatedPixmap = NULL; - crtc->rotatedData = NULL; - } - - for (c = 0; c < xf86_config->num_crtc; c++) - if (xf86_config->crtc[c]->transform_in_use) - return; - - /* - * Clean up damage structures when no crtcs are rotated - */ - if (xf86_config->rotation_damage) - { - /* Free damage structure */ - if (xf86_config->rotation_damage_registered) - { - DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, - xf86_config->rotation_damage); - xf86_config->rotation_damage_registered = FALSE; - DisableLimitedSchedulingLatency(); - } - DamageDestroy (xf86_config->rotation_damage); - xf86_config->rotation_damage = NULL; - } -} - -void -xf86RotateFreeShadow(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - - if (crtc->rotatedPixmap || crtc->rotatedData) { - crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, - crtc->rotatedData); - crtc->rotatedPixmap = NULL; - crtc->rotatedData = NULL; - } - } -} - -void -xf86RotateCloseScreen (ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - xf86RotateDestroy (xf86_config->crtc[c]); -} - -static Bool -xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb) -{ - ScrnInfoPtr pScrn = crtc->scrn; - BoxRec b; - - /* When called before PreInit, the driver is - * presumably doing load detect - */ - if (pScrn->virtualX == 0 || pScrn->virtualY == 0) - return TRUE; - - b.x1 = 0; - b.y1 = 0; - b.x2 = crtc->mode.HDisplay; - b.y2 = crtc->mode.VDisplay; - if (crtc_to_fb) - pixman_f_transform_bounds (crtc_to_fb, &b); - else { - b.x1 += crtc->x; - b.y1 += crtc->y; - b.x2 += crtc->x; - b.y2 += crtc->y; - } - - return (0 <= b.x1 && b.x2 <= pScrn->virtualX && - 0 <= b.y1 && b.y2 <= pScrn->virtualY); -} - -/* - * A subset of xf86CrtcRotate that just deals with - * cursor image/position transforms. Used when changing - * the cursor transform - */ -void -xf86CrtcRotateCursor (xf86CrtcPtr crtc) -{ - /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */ - RRTransformPtr transform = NULL; - PictTransform crtc_to_fb; - struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc, f_screen_to_crtc, f_crtc_to_cursor; - - if (crtc->transformPresent) - transform = &crtc->transform; - - (void) RRTransformCompute (crtc->x, crtc->y, - crtc->mode.HDisplay, crtc->mode.VDisplay, - crtc->rotation, - transform, - &crtc->user_sprite_position_transform, - &crtc->user_sprite_image_transform, - - &crtc_to_fb, - &f_crtc_to_fb, - &f_fb_to_crtc, - &f_screen_to_crtc, - &f_crtc_to_cursor, - &crtc->sprite_transform_in_use); - crtc->f_screen_to_crtc = f_screen_to_crtc; - crtc->f_crtc_to_cursor = f_crtc_to_cursor; -} - -Bool -xf86CrtcRotate (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */ - ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - PictTransform crtc_to_fb; - struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc, f_screen_to_crtc, f_crtc_to_cursor; - xFixed *new_params = NULL; - int new_nparams = 0; - PictFilterPtr new_filter = NULL; - int new_width = 0; - int new_height = 0; - RRTransformPtr transform = NULL; - Bool damage = FALSE; - - if (crtc->transformPresent) - transform = &crtc->transform; - - if (!RRTransformCompute (crtc->x, crtc->y, - crtc->mode.HDisplay, crtc->mode.VDisplay, - crtc->rotation, - transform, - &crtc->user_sprite_position_transform, - &crtc->user_sprite_image_transform, - - &crtc_to_fb, - &f_crtc_to_fb, - &f_fb_to_crtc, - &f_screen_to_crtc, - &f_crtc_to_cursor, - &crtc->sprite_transform_in_use) && - xf86CrtcFitsScreen (crtc, &f_crtc_to_fb)) - { - /* - * If the untranslated transformation is the identity, - * disable the shadow buffer - */ - xf86RotateDestroy (crtc); - crtc->transform_in_use = FALSE; - free(new_params); - new_params = NULL; - new_nparams = 0; - new_filter = NULL; - new_width = 0; - new_height = 0; - } - else - { - /* - * these are the size of the shadow pixmap, which - * matches the mode, not the pre-rotated copy in the - * frame buffer - */ - int width = crtc->mode.HDisplay; - int height = crtc->mode.VDisplay; - void *shadowData = crtc->rotatedData; - PixmapPtr shadow = crtc->rotatedPixmap; - int old_width = shadow ? shadow->drawable.width : 0; - int old_height = shadow ? shadow->drawable.height : 0; - - /* Allocate memory for rotation */ - if (old_width != width || old_height != height) - { - if (shadow || shadowData) - { - crtc->funcs->shadow_destroy (crtc, shadow, shadowData); - crtc->rotatedPixmap = NULL; - crtc->rotatedData = NULL; - } - shadowData = crtc->funcs->shadow_allocate (crtc, width, height); - if (!shadowData) - goto bail1; - crtc->rotatedData = shadowData; - /* shadow will be damaged in xf86RotatePrepare */ - } - else - { - /* mark shadowed area as damaged so it will be repainted */ - damage = TRUE; - } - - if (!xf86_config->rotation_damage) - { - /* Create damage structure */ - xf86_config->rotation_damage = DamageCreate (NULL, NULL, - DamageReportNone, - TRUE, pScreen, pScreen); - if (!xf86_config->rotation_damage) - goto bail2; - - /* Wrap block handler */ - if (!xf86_config->BlockHandler) { - xf86_config->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = xf86RotateBlockHandler; - } - } -#ifdef RANDR_12_INTERFACE - if (transform) - { - if (transform->nparams) { - new_params = malloc(transform->nparams * sizeof (xFixed)); - if (new_params) { - memcpy (new_params, transform->params, - transform->nparams * sizeof (xFixed)); - new_nparams = transform->nparams; - new_filter = transform->filter; - } - } else - new_filter = transform->filter; - if (new_filter) - { - new_width = new_filter->width; - new_height = new_filter->height; - } - } -#endif - - if (0) - { - bail2: - if (shadow || shadowData) - { - crtc->funcs->shadow_destroy (crtc, shadow, shadowData); - crtc->rotatedPixmap = NULL; - crtc->rotatedData = NULL; - } - bail1: - if (old_width && old_height) - crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, - NULL, - old_width, - old_height); - return FALSE; - } - crtc->transform_in_use = TRUE; - } - crtc->crtc_to_framebuffer = crtc_to_fb; - crtc->f_crtc_to_framebuffer = f_crtc_to_fb; - crtc->f_framebuffer_to_crtc = f_fb_to_crtc; - crtc->f_screen_to_crtc = f_screen_to_crtc; - crtc->f_crtc_to_cursor = f_crtc_to_cursor; - free(crtc->params); - crtc->params = new_params; - crtc->nparams = new_nparams; - crtc->filter = new_filter; - crtc->filter_width = new_width; - crtc->filter_height = new_height; - crtc->bounds.x1 = 0; - crtc->bounds.x2 = crtc->mode.HDisplay; - crtc->bounds.y1 = 0; - crtc->bounds.y2 = crtc->mode.VDisplay; - pixman_f_transform_bounds (&f_crtc_to_fb, &crtc->bounds); - - if (damage) - xf86CrtcDamageShadow (crtc); - - /* All done */ - return TRUE; -} +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#else +#ifdef HAVE_CONFIG_H +#include +#endif +#endif + +#include +#include +#include + +#include "xf86.h" +#include "xf86DDC.h" +#include "fb.h" +#include "windowstr.h" +#include "xf86Crtc.h" +#include "xf86Modes.h" +#include "xf86RandR12.h" +#include "X11/extensions/render.h" +#include "X11/extensions/dpmsconst.h" +#include "X11/Xatom.h" + +/* borrowed from composite extension, move to Render and publish? */ + +static VisualPtr +compGetWindowVisual (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + VisualID vid = wVisual (pWin); + int i; + + for (i = 0; i < pScreen->numVisuals; i++) + if (pScreen->visuals[i].vid == vid) + return &pScreen->visuals[i]; + return 0; +} + +static PictFormatPtr +compWindowFormat (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + return PictureMatchVisual (pScreen, pWin->drawable.depth, + compGetWindowVisual (pWin)); +} + +#define F(x) IntToxFixed(x) + +#define toF(x) ((float) (x) / 65536.0f) + +static void +xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) +{ + ScrnInfoPtr scrn = crtc->scrn; + ScreenPtr screen = scrn->pScreen; + WindowPtr root = screen->root; + PixmapPtr dst_pixmap = crtc->rotatedPixmap; + PictFormatPtr format = compWindowFormat (screen->root); + int error; + PicturePtr src, dst; + int n = RegionNumRects(region); + BoxPtr b = RegionRects(region); + XID include_inferiors = IncludeInferiors; + + src = CreatePicture (None, + &root->drawable, + format, + CPSubwindowMode, + &include_inferiors, + serverClient, + &error); + if (!src) + return; + + dst = CreatePicture (None, + &dst_pixmap->drawable, + format, + 0L, + NULL, + serverClient, + &error); + if (!dst) + return; + + error = SetPictureTransform (src, &crtc->crtc_to_framebuffer); + if (error) + return; + if (crtc->transform_in_use && crtc->filter) + SetPicturePictFilter (src, crtc->filter, + crtc->params, crtc->nparams); + + if (crtc->shadowClear) + { + CompositePicture (PictOpSrc, + src, NULL, dst, + 0, 0, 0, 0, 0, 0, + crtc->mode.HDisplay, crtc->mode.VDisplay); + crtc->shadowClear = FALSE; + } + else + { + while (n--) + { + BoxRec dst_box; + + dst_box = *b; + dst_box.x1 -= crtc->filter_width >> 1; + dst_box.x2 += crtc->filter_width >> 1; + dst_box.y1 -= crtc->filter_height >> 1; + dst_box.y2 += crtc->filter_height >> 1; + pixman_f_transform_bounds (&crtc->f_framebuffer_to_crtc, &dst_box); + CompositePicture (PictOpSrc, + src, NULL, dst, + dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1, + dst_box.x2 - dst_box.x1, + dst_box.y2 - dst_box.y1); + b++; + } + } + FreePicture (src, None); + FreePicture (dst, None); +} + +static void +xf86CrtcDamageShadow (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + BoxRec damage_box; + RegionRec damage_region; + ScreenPtr pScreen = pScrn->pScreen; + + damage_box.x1 = 0; + damage_box.x2 = crtc->mode.HDisplay; + damage_box.y1 = 0; + damage_box.y2 = crtc->mode.VDisplay; + if (!pixman_transform_bounds (&crtc->crtc_to_framebuffer, &damage_box)) + { + damage_box.x1 = 0; + damage_box.y1 = 0; + damage_box.x2 = pScreen->width; + damage_box.y2 = pScreen->height; + } + if (damage_box.x1 < 0) damage_box.x1 = 0; + if (damage_box.y1 < 0) damage_box.y1 = 0; + if (damage_box.x2 > pScreen->width) damage_box.x2 = pScreen->width; + if (damage_box.y2 > pScreen->height) damage_box.y2 = pScreen->height; + RegionInit(&damage_region, &damage_box, 1); + DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + &damage_region); + RegionUninit(&damage_region); + crtc->shadowClear = TRUE; +} + +static void +xf86RotatePrepare (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->rotatedData && !crtc->rotatedPixmap) + { + crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, + crtc->rotatedData, + crtc->mode.HDisplay, + crtc->mode.VDisplay); + if (!xf86_config->rotation_damage_registered) + { + /* Hook damage to screen pixmap */ + DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + xf86_config->rotation_damage); + xf86_config->rotation_damage_registered = TRUE; + EnableLimitedSchedulingLatency(); + } + + xf86CrtcDamageShadow (crtc); + } + } +} + +static Bool +xf86RotateRedisplay(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + DamagePtr damage = xf86_config->rotation_damage; + RegionPtr region; + + if (!damage) + return FALSE; + xf86RotatePrepare (pScreen); + region = DamageRegion(damage); + if (RegionNotEmpty(region)) + { + int c; + SourceValidateProcPtr SourceValidate; + + /* + * SourceValidate is used by the software cursor code + * to pull the cursor off of the screen when reading + * bits from the frame buffer. Bypassing this function + * leaves the software cursor in place + */ + SourceValidate = pScreen->SourceValidate; + pScreen->SourceValidate = NULL; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->transform_in_use && crtc->enabled) + { + RegionRec crtc_damage; + + /* compute portion of damage that overlaps crtc */ + RegionInit(&crtc_damage, &crtc->bounds, 1); + RegionIntersect(&crtc_damage, &crtc_damage, region); + + /* update damaged region */ + if (RegionNotEmpty(&crtc_damage)) + xf86RotateCrtcRedisplay (crtc, &crtc_damage); + + RegionUninit(&crtc_damage); + } + } + pScreen->SourceValidate = SourceValidate; + DamageEmpty(damage); + } + return TRUE; +} + +static void +xf86RotateBlockHandler(int screenNum, pointer blockData, + pointer pTimeout, pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[screenNum]; + ScrnInfoPtr pScrn = xf86Screens[screenNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + Bool rotation_active; + + rotation_active = xf86RotateRedisplay(pScreen); + pScreen->BlockHandler = xf86_config->BlockHandler; + (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); + /* cannot avoid re-wrapping until all wrapping is audited */ + xf86_config->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = xf86RotateBlockHandler; +} + +void +xf86RotateDestroy (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + ScreenPtr pScreen = pScrn->pScreen; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + /* Free memory from rotation */ + if (crtc->rotatedPixmap || crtc->rotatedData) + { + crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } + + for (c = 0; c < xf86_config->num_crtc; c++) + if (xf86_config->crtc[c]->transform_in_use) + return; + + /* + * Clean up damage structures when no crtcs are rotated + */ + if (xf86_config->rotation_damage) + { + /* Free damage structure */ + if (xf86_config->rotation_damage_registered) + { + DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + xf86_config->rotation_damage); + xf86_config->rotation_damage_registered = FALSE; + DisableLimitedSchedulingLatency(); + } + DamageDestroy (xf86_config->rotation_damage); + xf86_config->rotation_damage = NULL; + } +} + +void +xf86RotateFreeShadow(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + + if (crtc->rotatedPixmap || crtc->rotatedData) { + crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, + crtc->rotatedData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } + } +} + +void +xf86RotateCloseScreen (ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) + xf86RotateDestroy (xf86_config->crtc[c]); +} + +static Bool +xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb) +{ + ScrnInfoPtr pScrn = crtc->scrn; + BoxRec b; + + /* When called before PreInit, the driver is + * presumably doing load detect + */ + if (pScrn->virtualX == 0 || pScrn->virtualY == 0) + return TRUE; + + b.x1 = 0; + b.y1 = 0; + b.x2 = crtc->mode.HDisplay; + b.y2 = crtc->mode.VDisplay; + if (crtc_to_fb) + pixman_f_transform_bounds (crtc_to_fb, &b); + else { + b.x1 += crtc->x; + b.y1 += crtc->y; + b.x2 += crtc->x; + b.y2 += crtc->y; + } + + return (0 <= b.x1 && b.x2 <= pScrn->virtualX && + 0 <= b.y1 && b.y2 <= pScrn->virtualY); +} + +Bool +xf86CrtcRotate (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + PictTransform crtc_to_fb; + struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc; + xFixed *new_params = NULL; + int new_nparams = 0; + PictFilterPtr new_filter = NULL; + int new_width = 0; + int new_height = 0; + RRTransformPtr transform = NULL; + Bool damage = FALSE; + + if (crtc->transformPresent) + transform = &crtc->transform; + + if (!RRTransformCompute (crtc->x, crtc->y, + crtc->mode.HDisplay, crtc->mode.VDisplay, + crtc->rotation, + transform, + + &crtc_to_fb, + &f_crtc_to_fb, + &f_fb_to_crtc) && + xf86CrtcFitsScreen (crtc, &f_crtc_to_fb)) + { + /* + * If the untranslated transformation is the identity, + * disable the shadow buffer + */ + xf86RotateDestroy (crtc); + crtc->transform_in_use = FALSE; + free(new_params); + new_params = NULL; + new_nparams = 0; + new_filter = NULL; + new_width = 0; + new_height = 0; + } + else + { + /* + * these are the size of the shadow pixmap, which + * matches the mode, not the pre-rotated copy in the + * frame buffer + */ + int width = crtc->mode.HDisplay; + int height = crtc->mode.VDisplay; + void *shadowData = crtc->rotatedData; + PixmapPtr shadow = crtc->rotatedPixmap; + int old_width = shadow ? shadow->drawable.width : 0; + int old_height = shadow ? shadow->drawable.height : 0; + + /* Allocate memory for rotation */ + if (old_width != width || old_height != height) + { + if (shadow || shadowData) + { + crtc->funcs->shadow_destroy (crtc, shadow, shadowData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } + shadowData = crtc->funcs->shadow_allocate (crtc, width, height); + if (!shadowData) + goto bail1; + crtc->rotatedData = shadowData; + /* shadow will be damaged in xf86RotatePrepare */ + } + else + { + /* mark shadowed area as damaged so it will be repainted */ + damage = TRUE; + } + + if (!xf86_config->rotation_damage) + { + /* Create damage structure */ + xf86_config->rotation_damage = DamageCreate (NULL, NULL, + DamageReportNone, + TRUE, pScreen, pScreen); + if (!xf86_config->rotation_damage) + goto bail2; + + /* Wrap block handler */ + if (!xf86_config->BlockHandler) { + xf86_config->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = xf86RotateBlockHandler; + } + } +#ifdef RANDR_12_INTERFACE + if (transform) + { + if (transform->nparams) { + new_params = malloc(transform->nparams * sizeof (xFixed)); + if (new_params) { + memcpy (new_params, transform->params, + transform->nparams * sizeof (xFixed)); + new_nparams = transform->nparams; + new_filter = transform->filter; + } + } else + new_filter = transform->filter; + if (new_filter) + { + new_width = new_filter->width; + new_height = new_filter->height; + } + } +#endif + + if (0) + { + bail2: + if (shadow || shadowData) + { + crtc->funcs->shadow_destroy (crtc, shadow, shadowData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } + bail1: + if (old_width && old_height) + crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, + NULL, + old_width, + old_height); + return FALSE; + } + crtc->transform_in_use = TRUE; + } + crtc->crtc_to_framebuffer = crtc_to_fb; + crtc->f_crtc_to_framebuffer = f_crtc_to_fb; + crtc->f_framebuffer_to_crtc = f_fb_to_crtc; + free(crtc->params); + crtc->params = new_params; + crtc->nparams = new_nparams; + crtc->filter = new_filter; + crtc->filter_width = new_width; + crtc->filter_height = new_height; + crtc->bounds.x1 = 0; + crtc->bounds.x2 = crtc->mode.HDisplay; + crtc->bounds.y1 = 0; + crtc->bounds.y2 = crtc->mode.VDisplay; + pixman_f_transform_bounds (&f_crtc_to_fb, &crtc->bounds); + + if (damage) + xf86CrtcDamageShadow (crtc); + + /* All done */ + return TRUE; +} diff --git a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c index 62618afd8..123eb17d1 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c +++ b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c @@ -1,760 +1,756 @@ -/* - * Copyright 1992 by Rich Murphey - * Copyright 1993 by David Wexelblat - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the names of Rich Murphey and David Wexelblat - * not be used in advertising or publicity pertaining to distribution of - * the software without specific, written prior permission. Rich Murphey and - * David Wexelblat make no representations about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT BE LIABLE FOR - * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include - -#include "compiler.h" - -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86_OSlib.h" - -#include -#include -#include -#include - -static Bool KeepTty = FALSE; -static int devConsoleFd = -1; -#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) -static int VTnum = -1; -static int initialVT = -1; -static Bool ShareVTs = FALSE; -#endif - -#ifdef PCCONS_SUPPORT -/* Stock 0.1 386bsd pccons console driver interface */ -#ifndef __OpenBSD__ -# define PCCONS_CONSOLE_DEV1 "/dev/ttyv0" -#else -# define PCCONS_CONSOLE_DEV1 "/dev/ttyC0" -#endif -#define PCCONS_CONSOLE_DEV2 "/dev/vga" -#define PCCONS_CONSOLE_MODE O_RDWR|O_NDELAY -#endif - -#ifdef SYSCONS_SUPPORT -/* The FreeBSD 1.1 version syscons driver uses /dev/ttyv0 */ -#define SYSCONS_CONSOLE_DEV1 "/dev/ttyv0" -#define SYSCONS_CONSOLE_DEV2 "/dev/vga" -#define SYSCONS_CONSOLE_MODE O_RDWR|O_NDELAY -#endif - -#ifdef PCVT_SUPPORT -/* Hellmuth Michaelis' pcvt driver */ -#ifndef __OpenBSD__ -# define PCVT_CONSOLE_DEV "/dev/ttyv0" -#else -# define PCVT_CONSOLE_DEV "/dev/ttyC0" -#endif -#define PCVT_CONSOLE_MODE O_RDWR|O_NDELAY -#endif - -#if defined(WSCONS_SUPPORT) && defined(__NetBSD__) -/* NetBSD's new console driver */ -#define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0" -#endif - -#ifdef __GLIBC__ -#define setpgrp setpgid -#endif - -#define CHECK_DRIVER_MSG \ - "Check your kernel's console driver configuration and /dev entries" - -static char *supported_drivers[] = { -#ifdef PCCONS_SUPPORT - "pccons (with X support)", -#endif -#ifdef SYSCONS_SUPPORT - "syscons", -#endif -#ifdef PCVT_SUPPORT - "pcvt", -#endif -#ifdef WSCONS_SUPPORT - "wscons", -#endif -}; - - -/* - * Functions to probe for the existance of a supported console driver. - * Any function returns either a valid file descriptor (driver probed - * succesfully), -1 (driver not found), or uses FatalError() if the - * driver was found but proved to not support the required mode to run - * an X server. - */ - -typedef int (*xf86ConsOpen_t)(void); - -#ifdef PCCONS_SUPPORT -static int xf86OpenPccons(void); -#endif /* PCCONS_SUPPORT */ - -#ifdef SYSCONS_SUPPORT -static int xf86OpenSyscons(void); -#endif /* SYSCONS_SUPPORT */ - -#ifdef PCVT_SUPPORT -static int xf86OpenPcvt(void); -#endif /* PCVT_SUPPORT */ - -#ifdef WSCONS_SUPPORT -static int xf86OpenWScons(void); -#endif - -/* - * The sequence of the driver probes is important; start with the - * driver that is best distinguishable, and end with the most generic - * driver. (Otherwise, pcvt would also probe as syscons, and either - * pcvt or syscons might succesfully probe as pccons.) - */ -static xf86ConsOpen_t xf86ConsTab[] = { -#ifdef PCVT_SUPPORT - xf86OpenPcvt, -#endif -#ifdef SYSCONS_SUPPORT - xf86OpenSyscons, -#endif -#ifdef PCCONS_SUPPORT - xf86OpenPccons, -#endif -#ifdef WSCONS_SUPPORT - xf86OpenWScons, -#endif - (xf86ConsOpen_t)NULL -}; - - -void -xf86OpenConsole() -{ - int i, fd = -1; - xf86ConsOpen_t *driver; -#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) - int result; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - struct utsname uts; -#endif - vtmode_t vtmode; -#endif - - if (serverGeneration == 1) - { - /* check if we are run with euid==0 */ - if (geteuid() != 0) - { - FatalError("xf86OpenConsole: Server must be suid root"); - } - - if (!KeepTty) - { - /* - * detaching the controlling tty solves problems of kbd character - * loss. This is not interesting for CO driver, because it is - * exclusive. - */ - setpgrp(0, getpid()); - if ((i = open("/dev/tty",O_RDWR)) >= 0) - { - ioctl(i,TIOCNOTTY,(char *)0); - close(i); - } - } - - /* detect which driver we are running on */ - for (driver = xf86ConsTab; *driver; driver++) - { - if ((fd = (*driver)()) >= 0) - break; - } - - /* Check that a supported console driver was found */ - if (fd < 0) - { - char cons_drivers[80] = {0, }; - for (i = 0; i < sizeof(supported_drivers) / sizeof(char *); i++) - { - if (i) - { - strcat(cons_drivers, ", "); - } - strcat(cons_drivers, supported_drivers[i]); - } - FatalError( - "%s: No console driver found\n\tSupported drivers: %s\n\t%s", - "xf86OpenConsole", cons_drivers, CHECK_DRIVER_MSG); - } -#if 0 /* stdin is already closed in OsInit() */ - fclose(stdin); -#endif - xf86Info.consoleFd = fd; - xf86Info.screenFd = fd; - - switch (xf86Info.consType) - { -#ifdef PCCONS_SUPPORT - case PCCONS: - if (ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_ON, 0) < 0) - { - FatalError("%s: CONSOLE_X_MODE_ON failed (%s)\n%s", - "xf86OpenConsole", strerror(errno), - CHECK_DRIVER_MSG); - } - /* - * Hack to prevent keyboard hanging when syslogd closes - * /dev/console - */ - if ((devConsoleFd = open("/dev/console", O_WRONLY,0)) < 0) - { - xf86Msg(X_WARNING, - "xf86OpenConsole: couldn't open /dev/console (%s)\n", - strerror(errno)); - } - break; -#endif -#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) - case SYSCONS: - /* as of FreeBSD 2.2.8, syscons driver does not need the #1 vt - * switching anymore. Here we check for FreeBSD 3.1 and up. - * Add cases for other *BSD that behave the same. - */ -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - uname (&uts); - i = atof(uts.release) * 100; - if (i >= 310) goto acquire_vt; -#endif - /* otherwise fall through */ - case PCVT: -#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 200000000)) - /* - * First activate the #1 VT. This is a hack to allow a server - * to be started while another one is active. There should be - * a better way. - */ - if (initialVT != 1) { - - if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) != 0) - { - xf86Msg(X_WARNING, - "xf86OpenConsole: VT_ACTIVATE failed\n"); - } - sleep(1); - } -#endif -acquire_vt: - if (!ShareVTs) { - /* - * now get the VT - */ - SYSCALL(result = - ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno)); - if (result != 0) - { - xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); - } - SYSCALL(result = - ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno)); - if (result != 0) - { - xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); - } - - signal(SIGUSR1, xf86VTRequest); - - vtmode.mode = VT_PROCESS; - vtmode.relsig = SIGUSR1; - vtmode.acqsig = SIGUSR1; - vtmode.frsig = SIGUSR1; - if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0) - { - FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed"); - } - #if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) - if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0) - { - FatalError("xf86OpenConsole: KDENABIO failed (%s)", - strerror(errno)); - } - #endif - if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) - { - FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed"); - } - } else { /* ShareVTs */ - close(xf86Info.consoleFd); - } - break; -#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ -#ifdef WSCONS_SUPPORT - case WSCONS: - /* Nothing to do */ - break; -#endif - } - } - else - { - /* serverGeneration != 1 */ -#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) - if (!ShareVTs) if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) - { - if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) - { - xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); - } - } -#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ - } - return; -} - - -#ifdef PCCONS_SUPPORT - -static int -xf86OpenPccons() -{ - int fd = -1; - - if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0)) - >= 0 || - (fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0)) - >= 0) - { - if (ioctl(fd, CONSOLE_X_MODE_OFF, 0) < 0) - { - FatalError( - "%s: CONSOLE_X_MODE_OFF failed (%s)\n%s\n%s", - "xf86OpenPccons", - strerror(errno), - "Was expecting pccons driver with X support", - CHECK_DRIVER_MSG); - } - xf86Info.consType = PCCONS; - xf86Msg(X_PROBED, "Using pccons driver with X support\n"); - } - return fd; -} - -#endif /* PCCONS_SUPPORT */ - -#ifdef SYSCONS_SUPPORT - -static int -xf86OpenSyscons() -{ - int fd = -1; - vtmode_t vtmode; - char vtname[12]; - struct stat status; - long syscons_version; - MessageType from; - - /* Check for syscons */ - if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0 - || (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0) - { - if (ioctl(fd, VT_GETMODE, &vtmode) >= 0) - { - /* Get syscons version */ - if (ioctl(fd, CONS_GETVERS, &syscons_version) < 0) - { - syscons_version = 0; - } - - xf86Info.vtno = VTnum; - from = X_CMDLINE; - -#ifdef VT_GETACTIVE - if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0) - initialVT = -1; -#endif - if (ShareVTs) - xf86Info.vtno = initialVT; - - if (xf86Info.vtno == -1) - { - /* - * For old syscons versions (<0x100), VT_OPENQRY returns - * the current VT rather than the next free VT. In this - * case, the server gets started on the current VT instead - * of the next free VT. - */ - -#if 0 - /* check for the fixed VT_OPENQRY */ - if (syscons_version >= 0x100) - { -#endif - if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) - { - /* No free VTs */ - xf86Info.vtno = -1; - } -#if 0 - } -#endif - - if (xf86Info.vtno == -1) - { - /* - * All VTs are in use. If initialVT was found, use it. - * Otherwise, if stdin is a VT, use that one. - * XXX stdin is already closed, so this won't work. - */ - if (initialVT != -1) - { - xf86Info.vtno = initialVT; - } - else if ((fstat(0, &status) >= 0) - && S_ISCHR(status.st_mode) - && (ioctl(0, VT_GETMODE, &vtmode) >= 0)) - { - /* stdin is a VT */ - xf86Info.vtno = minor(status.st_rdev) + 1; - } - else - { - if (syscons_version >= 0x100) - { - FatalError("%s: Cannot find a free VT", - "xf86OpenSyscons"); - } - /* Should no longer reach here */ - FatalError("%s: %s %s\n\t%s %s", - "xf86OpenSyscons", - "syscons versions prior to 1.0 require", - "either the", - "server's stdin be a VT", - "or the use of the vtxx server option"); - } - } - from = X_PROBED; - } - - close(fd); -#ifndef __OpenBSD__ - sprintf(vtname, "/dev/ttyv%01x", xf86Info.vtno - 1); -#else - sprintf(vtname, "/dev/ttyC%01x", xf86Info.vtno - 1); -#endif - if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0) - { - FatalError("xf86OpenSyscons: Cannot open %s (%s)", - vtname, strerror(errno)); - } - if (ioctl(fd, VT_GETMODE, &vtmode) < 0) - { - FatalError("xf86OpenSyscons: VT_GETMODE failed"); - } - xf86Info.consType = SYSCONS; - xf86Msg(X_PROBED, "Using syscons driver with X support"); - if (syscons_version >= 0x100) - { - xf86ErrorF(" (version %ld.%ld)\n", syscons_version >> 8, - syscons_version & 0xFF); - } - else - { - xf86ErrorF(" (version 0.x)\n"); - } - xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno); - } - else - { - /* VT_GETMODE failed, probably not syscons */ - close(fd); - fd = -1; - } - } - return fd; -} - -#endif /* SYSCONS_SUPPORT */ - - -#ifdef PCVT_SUPPORT - -static int -xf86OpenPcvt() -{ - /* This looks much like syscons, since pcvt is API compatible */ - int fd = -1; - vtmode_t vtmode; - char vtname[12], *vtprefix; - struct stat status; - struct pcvtid pcvt_version; - -#ifndef __OpenBSD__ - vtprefix = "/dev/ttyv"; -#else - vtprefix = "/dev/ttyC"; -#endif - - fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0); -#ifdef WSCONS_PCVT_COMPAT_CONSOLE_DEV - if (fd < 0) - { - fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0); - vtprefix = "/dev/ttyE"; - } -#endif - if (fd >= 0) - { - if (ioctl(fd, VGAPCVTID, &pcvt_version) >= 0) - { - if(ioctl(fd, VT_GETMODE, &vtmode) < 0) - { - FatalError("%s: VT_GETMODE failed\n%s%s\n%s", - "xf86OpenPcvt", - "Found pcvt driver but X11 seems to be", - " not supported.", CHECK_DRIVER_MSG); - } - - xf86Info.vtno = VTnum; - - if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0) - initialVT = -1; - - if (xf86Info.vtno == -1) - { - if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) - { - /* No free VTs */ - xf86Info.vtno = -1; - } - - if (xf86Info.vtno == -1) - { - /* - * All VTs are in use. If initialVT was found, use it. - * Otherwise, if stdin is a VT, use that one. - * XXX stdin is already closed, so this won't work. - */ - if (initialVT != -1) - { - xf86Info.vtno = initialVT; - } - else if ((fstat(0, &status) >= 0) - && S_ISCHR(status.st_mode) - && (ioctl(0, VT_GETMODE, &vtmode) >= 0)) - { - /* stdin is a VT */ - xf86Info.vtno = minor(status.st_rdev) + 1; - } - else - { - FatalError("%s: Cannot find a free VT", - "xf86OpenPcvt"); - } - } - } - - close(fd); - sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); - if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) - { - ErrorF("xf86OpenPcvt: Cannot open %s (%s)", - vtname, strerror(errno)); - xf86Info.vtno = initialVT; - sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); - if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) { - FatalError("xf86OpenPcvt: Cannot open %s (%s)", - vtname, strerror(errno)); - } - } - if (ioctl(fd, VT_GETMODE, &vtmode) < 0) - { - FatalError("xf86OpenPcvt: VT_GETMODE failed"); - } - xf86Info.consType = PCVT; -#ifdef WSCONS_SUPPORT - xf86Msg(X_PROBED, - "Using wscons driver on %s in pcvt compatibility mode " - "(version %d.%d)\n", vtname, - pcvt_version.rmajor, pcvt_version.rminor); -#else - xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n", - pcvt_version.rmajor, pcvt_version.rminor); -#endif - } - else - { - /* Not pcvt */ - close(fd); - fd = -1; - } - } - return fd; -} - -#endif /* PCVT_SUPPORT */ - -#ifdef WSCONS_SUPPORT - -static int -xf86OpenWScons() -{ - int fd = -1; - int mode = WSDISPLAYIO_MODE_MAPPED; - int i; - char ttyname[16]; - - /* XXX Is this ok? */ - for (i = 0; i < 8; i++) { -#if defined(__NetBSD__) - sprintf(ttyname, "/dev/ttyE%d", i); -#elif defined(__OpenBSD__) - sprintf(ttyname, "/dev/ttyC%x", i); -#endif - if ((fd = open(ttyname, 2)) != -1) - break; - } - if (fd != -1) { - if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) < 0) { - FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed (%s)\n%s", - "xf86OpenConsole", strerror(errno), - CHECK_DRIVER_MSG); - } - xf86Info.consType = WSCONS; - xf86Msg(X_PROBED, "Using wscons driver\n"); - } - return fd; -} - -#endif /* WSCONS_SUPPORT */ - -void -xf86CloseConsole() -{ -#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) - struct vt_mode VT; -#endif - - if (ShareVTs) return; - - switch (xf86Info.consType) - { -#ifdef PCCONS_SUPPORT - case PCCONS: - ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_OFF, 0); - break; -#endif /* PCCONS_SUPPORT */ -#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) - case SYSCONS: - case PCVT: - ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode */ - if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) - { - VT.mode = VT_AUTO; - ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* dflt vt handling */ - } -#if !defined(OpenBSD) && !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) - if (ioctl(xf86Info.consoleFd, KDDISABIO, 0) < 0) - { - xf86FatalError("xf86CloseConsole: KDDISABIO failed (%s)", - strerror(errno)); - } -#endif - if (initialVT != -1) - ioctl(xf86Info.consoleFd, VT_ACTIVATE, initialVT); - break; -#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ -#ifdef WSCONS_SUPPORT - case WSCONS: - { - int mode = WSDISPLAYIO_MODE_EMUL; - ioctl(xf86Info.screenFd, WSDISPLAYIO_SMODE, &mode); - break; - } -#endif - } - - if (xf86Info.screenFd != xf86Info.consoleFd) - { - close(xf86Info.screenFd); - close(xf86Info.consoleFd); - if ((xf86Info.consoleFd = open("/dev/console",O_RDONLY,0)) <0) - { - xf86FatalError("xf86CloseConsole: Cannot open /dev/console (%s)", - strerror(errno)); - } - } - close(xf86Info.consoleFd); - if (devConsoleFd >= 0) - close(devConsoleFd); - return; -} - -int -xf86ProcessArgument(int argc, char *argv[], int i) -{ - /* - * Keep server from detaching from controlling tty. This is useful - * when debugging (so the server can receive keyboard signals. - */ - if (!strcmp(argv[i], "-keeptty")) - { - KeepTty = TRUE; - return 1; - } -#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) - if (!strcmp(argv[i], "-sharevts")) - { - ShareVTs = TRUE; - return 1; - } - if ((argv[i][0] == 'v') && (argv[i][1] == 't')) - { - if (sscanf(argv[i], "vt%2d", &VTnum) == 0 || - VTnum < 1 || VTnum > 12) - { - UseMsg(); - VTnum = -1; - return 0; - } - return 1; - } -#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ - return 0; -} - -void -xf86UseMsg() -{ -#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) - ErrorF("vtXX use the specified VT number (1-12)\n"); - ErrorF("-sharevts share VTs with another X server\n"); -#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ - ErrorF("-keeptty "); - ErrorF("don't detach controlling tty (for debugging only)\n"); - return; -} +/* + * Copyright 1992 by Rich Murphey + * Copyright 1993 by David Wexelblat + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Rich Murphey and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Rich Murphey and + * David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include +#include +#include +#include + +static Bool KeepTty = FALSE; +static int devConsoleFd = -1; +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) +static int VTnum = -1; +static int initialVT = -1; +static Bool ShareVTs = FALSE; +#endif + +#ifdef PCCONS_SUPPORT +/* Stock 0.1 386bsd pccons console driver interface */ +#define PCCONS_CONSOLE_DEV1 "/dev/ttyv0" +#define PCCONS_CONSOLE_DEV2 "/dev/vga" +#define PCCONS_CONSOLE_MODE O_RDWR|O_NDELAY +#endif + +#ifdef SYSCONS_SUPPORT +/* The FreeBSD 1.1 version syscons driver uses /dev/ttyv0 */ +#define SYSCONS_CONSOLE_DEV1 "/dev/ttyv0" +#define SYSCONS_CONSOLE_DEV2 "/dev/vga" +#define SYSCONS_CONSOLE_MODE O_RDWR|O_NDELAY +#endif + +#ifdef PCVT_SUPPORT +/* Hellmuth Michaelis' pcvt driver */ +#ifndef __OpenBSD__ +# define PCVT_CONSOLE_DEV "/dev/ttyv0" +#else +# define PCVT_CONSOLE_DEV "/dev/ttyC0" +#endif +#define PCVT_CONSOLE_MODE O_RDWR|O_NDELAY +#endif + +#if defined(WSCONS_SUPPORT) && defined(__NetBSD__) +/* NetBSD's new console driver */ +#define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0" +#endif + +#ifdef __GLIBC__ +#define setpgrp setpgid +#endif + +#define CHECK_DRIVER_MSG \ + "Check your kernel's console driver configuration and /dev entries" + +static char *supported_drivers[] = { +#ifdef PCCONS_SUPPORT + "pccons (with X support)", +#endif +#ifdef SYSCONS_SUPPORT + "syscons", +#endif +#ifdef PCVT_SUPPORT + "pcvt", +#endif +#ifdef WSCONS_SUPPORT + "wscons", +#endif +}; + + +/* + * Functions to probe for the existance of a supported console driver. + * Any function returns either a valid file descriptor (driver probed + * succesfully), -1 (driver not found), or uses FatalError() if the + * driver was found but proved to not support the required mode to run + * an X server. + */ + +typedef int (*xf86ConsOpen_t)(void); + +#ifdef PCCONS_SUPPORT +static int xf86OpenPccons(void); +#endif /* PCCONS_SUPPORT */ + +#ifdef SYSCONS_SUPPORT +static int xf86OpenSyscons(void); +#endif /* SYSCONS_SUPPORT */ + +#ifdef PCVT_SUPPORT +static int xf86OpenPcvt(void); +#endif /* PCVT_SUPPORT */ + +#ifdef WSCONS_SUPPORT +static int xf86OpenWScons(void); +#endif + +/* + * The sequence of the driver probes is important; start with the + * driver that is best distinguishable, and end with the most generic + * driver. (Otherwise, pcvt would also probe as syscons, and either + * pcvt or syscons might succesfully probe as pccons.) + */ +static xf86ConsOpen_t xf86ConsTab[] = { +#ifdef PCVT_SUPPORT + xf86OpenPcvt, +#endif +#ifdef SYSCONS_SUPPORT + xf86OpenSyscons, +#endif +#ifdef PCCONS_SUPPORT + xf86OpenPccons, +#endif +#ifdef WSCONS_SUPPORT + xf86OpenWScons, +#endif + (xf86ConsOpen_t)NULL +}; + + +void +xf86OpenConsole() +{ + int i, fd = -1; + xf86ConsOpen_t *driver; +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + int result; +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + struct utsname uts; +#endif + vtmode_t vtmode; +#endif + + if (serverGeneration == 1) + { + /* check if we are run with euid==0 */ + if (geteuid() != 0) + { + FatalError("xf86OpenConsole: Server must be suid root"); + } + + if (!KeepTty) + { + /* + * detaching the controlling tty solves problems of kbd character + * loss. This is not interesting for CO driver, because it is + * exclusive. + */ + setpgrp(0, getpid()); + if ((i = open("/dev/tty",O_RDWR)) >= 0) + { + ioctl(i,TIOCNOTTY,(char *)0); + close(i); + } + } + + /* detect which driver we are running on */ + for (driver = xf86ConsTab; *driver; driver++) + { + if ((fd = (*driver)()) >= 0) + break; + } + + /* Check that a supported console driver was found */ + if (fd < 0) + { + char cons_drivers[80] = {0, }; + for (i = 0; i < sizeof(supported_drivers) / sizeof(char *); i++) + { + if (i) + { + strcat(cons_drivers, ", "); + } + strcat(cons_drivers, supported_drivers[i]); + } + FatalError( + "%s: No console driver found\n\tSupported drivers: %s\n\t%s", + "xf86OpenConsole", cons_drivers, CHECK_DRIVER_MSG); + } +#if 0 /* stdin is already closed in OsInit() */ + fclose(stdin); +#endif + xf86Info.consoleFd = fd; + xf86Info.screenFd = fd; + + switch (xf86Info.consType) + { +#ifdef PCCONS_SUPPORT + case PCCONS: + if (ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_ON, 0) < 0) + { + FatalError("%s: CONSOLE_X_MODE_ON failed (%s)\n%s", + "xf86OpenConsole", strerror(errno), + CHECK_DRIVER_MSG); + } + /* + * Hack to prevent keyboard hanging when syslogd closes + * /dev/console + */ + if ((devConsoleFd = open("/dev/console", O_WRONLY,0)) < 0) + { + xf86Msg(X_WARNING, + "xf86OpenConsole: couldn't open /dev/console (%s)\n", + strerror(errno)); + } + break; +#endif +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + case SYSCONS: + /* as of FreeBSD 2.2.8, syscons driver does not need the #1 vt + * switching anymore. Here we check for FreeBSD 3.1 and up. + * Add cases for other *BSD that behave the same. + */ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + uname (&uts); + i = atof(uts.release) * 100; + if (i >= 310) goto acquire_vt; +#endif + /* otherwise fall through */ + case PCVT: +#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 200000000)) + /* + * First activate the #1 VT. This is a hack to allow a server + * to be started while another one is active. There should be + * a better way. + */ + if (initialVT != 1) { + + if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) != 0) + { + xf86Msg(X_WARNING, + "xf86OpenConsole: VT_ACTIVATE failed\n"); + } + sleep(1); + } +#endif +acquire_vt: + if (!ShareVTs) { + /* + * now get the VT + */ + SYSCALL(result = + ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno)); + if (result != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); + } + SYSCALL(result = + ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno)); + if (result != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); + } + + signal(SIGUSR1, xf86VTRequest); + + vtmode.mode = VT_PROCESS; + vtmode.relsig = SIGUSR1; + vtmode.acqsig = SIGUSR1; + vtmode.frsig = SIGUSR1; + if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0) + { + FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed"); + } + #if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) + if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0) + { + FatalError("xf86OpenConsole: KDENABIO failed (%s)", + strerror(errno)); + } + #endif + if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) + { + FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed"); + } + } else { /* ShareVTs */ + close(xf86Info.consoleFd); + } + break; +#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ +#ifdef WSCONS_SUPPORT + case WSCONS: + /* Nothing to do */ + break; +#endif + } + } + else + { + /* serverGeneration != 1 */ +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + if (!ShareVTs) if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) + { + if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); + } + } +#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ + } + return; +} + + +#ifdef PCCONS_SUPPORT + +static int +xf86OpenPccons() +{ + int fd = -1; + + if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0)) + >= 0 || + (fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0)) + >= 0) + { + if (ioctl(fd, CONSOLE_X_MODE_OFF, 0) < 0) + { + FatalError( + "%s: CONSOLE_X_MODE_OFF failed (%s)\n%s\n%s", + "xf86OpenPccons", + strerror(errno), + "Was expecting pccons driver with X support", + CHECK_DRIVER_MSG); + } + xf86Info.consType = PCCONS; + xf86Msg(X_PROBED, "Using pccons driver with X support\n"); + } + return fd; +} + +#endif /* PCCONS_SUPPORT */ + +#ifdef SYSCONS_SUPPORT + +static int +xf86OpenSyscons() +{ + int fd = -1; + vtmode_t vtmode; + char vtname[12]; + struct stat status; + long syscons_version; + MessageType from; + + /* Check for syscons */ + if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0 + || (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0) + { + if (ioctl(fd, VT_GETMODE, &vtmode) >= 0) + { + /* Get syscons version */ + if (ioctl(fd, CONS_GETVERS, &syscons_version) < 0) + { + syscons_version = 0; + } + + xf86Info.vtno = VTnum; + from = X_CMDLINE; + +#ifdef VT_GETACTIVE + if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0) + initialVT = -1; +#endif + if (ShareVTs) + xf86Info.vtno = initialVT; + + if (xf86Info.vtno == -1) + { + /* + * For old syscons versions (<0x100), VT_OPENQRY returns + * the current VT rather than the next free VT. In this + * case, the server gets started on the current VT instead + * of the next free VT. + */ + +#if 0 + /* check for the fixed VT_OPENQRY */ + if (syscons_version >= 0x100) + { +#endif + if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) + { + /* No free VTs */ + xf86Info.vtno = -1; + } +#if 0 + } +#endif + + if (xf86Info.vtno == -1) + { + /* + * All VTs are in use. If initialVT was found, use it. + * Otherwise, if stdin is a VT, use that one. + * XXX stdin is already closed, so this won't work. + */ + if (initialVT != -1) + { + xf86Info.vtno = initialVT; + } + else if ((fstat(0, &status) >= 0) + && S_ISCHR(status.st_mode) + && (ioctl(0, VT_GETMODE, &vtmode) >= 0)) + { + /* stdin is a VT */ + xf86Info.vtno = minor(status.st_rdev) + 1; + } + else + { + if (syscons_version >= 0x100) + { + FatalError("%s: Cannot find a free VT", + "xf86OpenSyscons"); + } + /* Should no longer reach here */ + FatalError("%s: %s %s\n\t%s %s", + "xf86OpenSyscons", + "syscons versions prior to 1.0 require", + "either the", + "server's stdin be a VT", + "or the use of the vtxx server option"); + } + } + from = X_PROBED; + } + + close(fd); +#ifndef __OpenBSD__ + sprintf(vtname, "/dev/ttyv%01x", xf86Info.vtno - 1); +#else + sprintf(vtname, "/dev/ttyC%01x", xf86Info.vtno - 1); +#endif + if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0) + { + FatalError("xf86OpenSyscons: Cannot open %s (%s)", + vtname, strerror(errno)); + } + if (ioctl(fd, VT_GETMODE, &vtmode) < 0) + { + FatalError("xf86OpenSyscons: VT_GETMODE failed"); + } + xf86Info.consType = SYSCONS; + xf86Msg(X_PROBED, "Using syscons driver with X support"); + if (syscons_version >= 0x100) + { + xf86ErrorF(" (version %ld.%ld)\n", syscons_version >> 8, + syscons_version & 0xFF); + } + else + { + xf86ErrorF(" (version 0.x)\n"); + } + xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno); + } + else + { + /* VT_GETMODE failed, probably not syscons */ + close(fd); + fd = -1; + } + } + return fd; +} + +#endif /* SYSCONS_SUPPORT */ + + +#ifdef PCVT_SUPPORT + +static int +xf86OpenPcvt() +{ + /* This looks much like syscons, since pcvt is API compatible */ + int fd = -1; + vtmode_t vtmode; + char vtname[12], *vtprefix; + struct stat status; + struct pcvtid pcvt_version; + +#ifndef __OpenBSD__ + vtprefix = "/dev/ttyv"; +#else + vtprefix = "/dev/ttyC"; +#endif + + fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0); +#ifdef WSCONS_PCVT_COMPAT_CONSOLE_DEV + if (fd < 0) + { + fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0); + vtprefix = "/dev/ttyE"; + } +#endif + if (fd >= 0) + { + if (ioctl(fd, VGAPCVTID, &pcvt_version) >= 0) + { + if(ioctl(fd, VT_GETMODE, &vtmode) < 0) + { + FatalError("%s: VT_GETMODE failed\n%s%s\n%s", + "xf86OpenPcvt", + "Found pcvt driver but X11 seems to be", + " not supported.", CHECK_DRIVER_MSG); + } + + xf86Info.vtno = VTnum; + + if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0) + initialVT = -1; + + if (xf86Info.vtno == -1) + { + if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) + { + /* No free VTs */ + xf86Info.vtno = -1; + } + + if (xf86Info.vtno == -1) + { + /* + * All VTs are in use. If initialVT was found, use it. + * Otherwise, if stdin is a VT, use that one. + * XXX stdin is already closed, so this won't work. + */ + if (initialVT != -1) + { + xf86Info.vtno = initialVT; + } + else if ((fstat(0, &status) >= 0) + && S_ISCHR(status.st_mode) + && (ioctl(0, VT_GETMODE, &vtmode) >= 0)) + { + /* stdin is a VT */ + xf86Info.vtno = minor(status.st_rdev) + 1; + } + else + { + FatalError("%s: Cannot find a free VT", + "xf86OpenPcvt"); + } + } + } + + close(fd); + sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); + if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) + { + ErrorF("xf86OpenPcvt: Cannot open %s (%s)", + vtname, strerror(errno)); + xf86Info.vtno = initialVT; + sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); + if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) { + FatalError("xf86OpenPcvt: Cannot open %s (%s)", + vtname, strerror(errno)); + } + } + if (ioctl(fd, VT_GETMODE, &vtmode) < 0) + { + FatalError("xf86OpenPcvt: VT_GETMODE failed"); + } + xf86Info.consType = PCVT; +#ifdef WSCONS_SUPPORT + xf86Msg(X_PROBED, + "Using wscons driver on %s in pcvt compatibility mode " + "(version %d.%d)\n", vtname, + pcvt_version.rmajor, pcvt_version.rminor); +#else + xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n", + pcvt_version.rmajor, pcvt_version.rminor); +#endif + } + else + { + /* Not pcvt */ + close(fd); + fd = -1; + } + } + return fd; +} + +#endif /* PCVT_SUPPORT */ + +#ifdef WSCONS_SUPPORT + +static int +xf86OpenWScons() +{ + int fd = -1; + int mode = WSDISPLAYIO_MODE_MAPPED; + int i; + char ttyname[16]; + + /* XXX Is this ok? */ + for (i = 0; i < 8; i++) { +#if defined(__NetBSD__) + sprintf(ttyname, "/dev/ttyE%d", i); +#elif defined(__OpenBSD__) + sprintf(ttyname, "/dev/ttyC%x", i); +#endif + if ((fd = open(ttyname, 2)) != -1) + break; + } + if (fd != -1) { + if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) < 0) { + FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed (%s)\n%s", + "xf86OpenConsole", strerror(errno), + CHECK_DRIVER_MSG); + } + xf86Info.consType = WSCONS; + xf86Msg(X_PROBED, "Using wscons driver\n"); + } + return fd; +} + +#endif /* WSCONS_SUPPORT */ + +void +xf86CloseConsole() +{ +#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) + struct vt_mode VT; +#endif + + if (ShareVTs) return; + + switch (xf86Info.consType) + { +#ifdef PCCONS_SUPPORT + case PCCONS: + ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_OFF, 0); + break; +#endif /* PCCONS_SUPPORT */ +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + case SYSCONS: + case PCVT: + ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode */ + if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) + { + VT.mode = VT_AUTO; + ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* dflt vt handling */ + } +#if !defined(OpenBSD) && !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) + if (ioctl(xf86Info.consoleFd, KDDISABIO, 0) < 0) + { + xf86FatalError("xf86CloseConsole: KDDISABIO failed (%s)", + strerror(errno)); + } +#endif + if (initialVT != -1) + ioctl(xf86Info.consoleFd, VT_ACTIVATE, initialVT); + break; +#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ +#ifdef WSCONS_SUPPORT + case WSCONS: + { + int mode = WSDISPLAYIO_MODE_EMUL; + ioctl(xf86Info.screenFd, WSDISPLAYIO_SMODE, &mode); + break; + } +#endif + } + + if (xf86Info.screenFd != xf86Info.consoleFd) + { + close(xf86Info.screenFd); + close(xf86Info.consoleFd); + if ((xf86Info.consoleFd = open("/dev/console",O_RDONLY,0)) <0) + { + xf86FatalError("xf86CloseConsole: Cannot open /dev/console (%s)", + strerror(errno)); + } + } + close(xf86Info.consoleFd); + if (devConsoleFd >= 0) + close(devConsoleFd); + return; +} + +int +xf86ProcessArgument(int argc, char *argv[], int i) +{ + /* + * Keep server from detaching from controlling tty. This is useful + * when debugging (so the server can receive keyboard signals. + */ + if (!strcmp(argv[i], "-keeptty")) + { + KeepTty = TRUE; + return 1; + } +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + if (!strcmp(argv[i], "-sharevts")) + { + ShareVTs = TRUE; + return 1; + } + if ((argv[i][0] == 'v') && (argv[i][1] == 't')) + { + if (sscanf(argv[i], "vt%2d", &VTnum) == 0 || + VTnum < 1 || VTnum > 12) + { + UseMsg(); + VTnum = -1; + return 0; + } + return 1; + } +#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ + return 0; +} + +void +xf86UseMsg() +{ +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + ErrorF("vtXX use the specified VT number (1-12)\n"); + ErrorF("-sharevts share VTs with another X server\n"); +#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ + ErrorF("-keeptty "); + ErrorF("don't detach controlling tty (for debugging only)\n"); + return; +} diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h index 3b646da70..147a201ee 100644 --- a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h +++ b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h @@ -264,14 +264,6 @@ # define CONSOLE_X_MODE_OFF PCCONIOCCOOK # define CONSOLE_X_BELL PCCONIOCBEEP # else /* __bsdi__ */ -# if defined(__OpenBSD__) -# ifdef PCCONS_SUPPORT -# include -# undef CONSOLE_X_MODE_ON -# undef CONSOLE_X_MODE_OFF -# undef CONSOLE_X_BELL -# endif -# endif # ifdef SYSCONS_SUPPORT # define COMPAT_SYSCONS # if defined(__NetBSD__) || defined(__OpenBSD__) diff --git a/xorg-server/hw/xquartz/bundle/Info.plist.cpp b/xorg-server/hw/xquartz/bundle/Info.plist.cpp index 2e568ffeb..0e98218be 100644 --- a/xorg-server/hw/xquartz/bundle/Info.plist.cpp +++ b/xorg-server/hw/xquartz/bundle/Info.plist.cpp @@ -34,6 +34,8 @@ SUFeedURL http://xquartz.macosforge.org/downloads/sparkle/release.xml #endif + LSApplicationCategoryType + public.app-category.utilities NSHumanReadableCopyright © 2003-2011 Apple Inc. © 2003 XFree86 Project, Inc. diff --git a/xorg-server/hw/xquartz/bundle/Resources/French.lproj/locversion.plist b/xorg-server/hw/xquartz/bundle/Resources/French.lproj/locversion.plist index 80a63fd48..1af1256c3 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/French.lproj/locversion.plist +++ b/xorg-server/hw/xquartz/bundle/Resources/French.lproj/locversion.plist @@ -1,14 +1,14 @@ - - - - - LprojCompatibleVersion - 98 - LprojLocale - fr - LprojRevisionLevel - 1 - LprojVersion - 98 - - + + + + + LprojCompatibleVersion + 101 + LprojLocale + fr + LprojRevisionLevel + 1 + LprojVersion + 101 + + diff --git a/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/designable.nib b/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/designable.nib index 7c35a1a60..cec363241 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/designable.nib +++ b/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/designable.nib @@ -1,3616 +1,3767 @@ - - - - 1040 - 11A194b - 787 - 1079 - 502.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 787 - - - - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - NSApplication - - - - FirstResponder - - - NSApplication - - - MainMenu - - - - X11 - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - X11 - - - - À propos d’X11 - - 2147483647 - - - - - - Préférences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - - Services - - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Basculer en mode plein écran - a - 1572864 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Masquer X11 - h - 1048576 - 2147483647 - - - 42 - - - - Masquer les autres - h - 1572864 - 2147483647 - - - - - - Tout afficher - - 1048576 - 2147483647 - - - 42 - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quitter X11 - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - Applications - - 1048576 - 2147483647 - - - submenuAction: - - Applications - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Personnaliser… - - 1048576 - 2147483647 - - - - - - - - - Édition - - 1048576 - 2147483647 - - - submenuAction: - - Édition - - - - Copier - c - 1048576 - 2147483647 - - - - - - - - - Fenêtre - - 1048576 - 2147483647 - - - submenuAction: - - Fenêtre - - - - Fermer - w - 1048576 - 2147483647 - - - - - - Placer dans le Dock - m - 1048576 - 2147483647 - - - - - - Réduire/agrandir - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Faire défiler les fenêtres - ` - 1048840 - 2147483647 - - - - - - Faire défiler les fenêtres en sens inverse - ` - 1179648 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Tout ramener au premier plan - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Aide - - 1048576 - 2147483647 - - - submenuAction: - - Aide - - - - Aide X11 - - 1048576 - 2147483647 - - - - - - - - _NSMainMenu - - - X11Controller - - - 3 - 2 - {{414, 417}, {582, 329}} - 1350041600 - Préférences d’X11 - NSPanel - - View - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - {320, 240} - - - 256 - - - - 256 - {{13, 10}, {556, 313}} - - - - - 1 - - - - 256 - - - - 256 - {{67, 235}, {402, 18}} - - YES - - 67239424 - 0 - Émuler une souris à trois boutons - - LucidaGrande - 13 - 1044 - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 256 - {{85, 64}, {385, 42}} - - YES - - 67239424 - 4194304 - Quand cette option est activée, les touches équivalentes de la barre des menus peuvent perturber les applications X11 qui utilisent le modificateur d’instructions virtuelles. - - LucidaGrande - 11 - 3100 - - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 256 - {{85, 195}, {385, 34}} - - YES - - 67239424 - 4194304 - TWFpbnRlbmV6IGxhIHRvdWNoZSBPcHRpb24gb3UgQ29tbWFuZGUgZW5mb25jw6llIHRvdXQgZW4gY2xp -cXVhbnQgcG91ciBhY3RpdmVyIGxlIGJvdXRvbiBkcm9pdCBvdSBjZW50cmFsIGRlIGxhIHNvdXJpcy4K -A - - - - - - - - - - 256 - {{67, 112}, {402, 18}} - - YES - - 67239424 - 0 - Activer les touches équivalentes sous X11 - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{85, 136}, {385, 29}} - - YES - - 67239424 - 4194304 - Autorise les modifications du menu d’entrée pour remplacer la disposition des touches du clavier X11. - - - - - - - - - - 256 - {{67, 171}, {402, 18}} - - YES - - 67239424 - 0 - Utiliser la disposition des touches du clavier du système - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{85, 6}, {385, 28}} - - YES - - 67239424 - 4194304 - Une fois activées, les touches option envoient les symboles Alt_L et Alt_R au lieu de Mode_switch. - - - - - - - - - 256 - {{67, 40}, {402, 18}} - - YES - - 67239424 - 0 - Les touches option envoient Alt_L et Alt_R - - - 1211912703 - 2 - - - - - 200 - 25 - - - - {{10, 33}, {536, 267}} - - Entrée - - - - - - 2 - - - - 256 - - - - 256 - {{34, 84}, {402, 18}} - - YES - - 67239424 - 0 - Utiliser l’effet d’avertissement du système - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{52, 50}, {385, 28}} - - YES - - 67239424 - 4194304 - Les sons émis par X11 utiliseront l’avertissement standard du système, comme défini dans le panneau Effets sonores des Préférences Système. - - - - - - - - - - 256 - {{104, 223}, {128, 26}} - - YES - - -2076049856 - 1024 - - - 109199615 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - du moniteur - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - -1 - - - YES - - - OtherViews - - - - - - 256 couleurs - - 1048576 - 2147483647 - - - _popUpItemAction: - 8 - - - - - milliers - - 1048576 - 2147483647 - - - _popUpItemAction: - 15 - - - - - millions - - 1048576 - 2147483647 - - - _popUpItemAction: - 24 - - - - - 3 - YES - YES - 1 - - - - - 256 - {{33, 226}, {71, 20}} - - YES - - 67239424 - 4194304 - Couleurs : - - - - - - - - - - 256 - {{52, 204}, {392, 14}} - - YES - - 67239424 - 4194304 - Cette option prend effet au prochain lancement d’X11. - - - - - - - - - - 256 - {{34, 170}, {409, 23}} - - YES - - 67239424 - 0 - Mode plein écran - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{53, 109}, {445, 18}} - - YES - - 67239424 - 0 - Afficher automatiquement la barre des menus en mode plein écran - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{52, 133}, {385, 31}} - - YES - - 67239424 - 4194304 - Active la fenêtre root X11. Utilisez le raccourci clavier Commande + Option + A pour ouvrir et fermer le mode plein écran. - - - - - - - - - {{10, 33}, {536, 267}} - - Sortie - - - - - - 2 - - - - 256 - - - - 256 - {{25, 235}, {409, 23}} - - YES - - 67239424 - 0 - Activer la synchronisation - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{43, 187}, {378, 42}} - - YES - - 67239424 - 4194304 - Active la commande de menu « Copier » et permet la synchronisation entre le presse-papiers de OSX, celui de X11 (CLIPBOARD) et les mémoires tampons principales (PRIMARY). - - - - - - - - - 256 - {{41, 105}, {424, 18}} - - YES - - 67239424 - 0 - Mettre à jour CLIPBOARD lorsque le presse-papiers est modifié - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{41, 83}, {489, 18}} - - YES - - 67239424 - 0 - Mettre à jour PRIMARY (clic central) lorsque le presse-papiers est modifié - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{41, 61}, {437, 18}} - - YES - - 67239424 - 0 - Mettre à jour le presse-papiers dès la sélection de nouveau texte - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{41, 163}, {424, 18}} - - YES - - 67239424 - 0 - Mettre à jour le presse-papiers lorsque CLIPBOARD est modifié - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{55, 129}, {385, 28}} - - YES - - 67239424 - 4194304 - Désactivez cette option si vous voulez utiliser xclipboard, klipper, ou tout autre gestionnaire de presse-papiers X11. - - - - - - - - - 256 - {{55, 29}, {385, 28}} - - YES - - 67239424 - 4194304 - En raison de limitations du protocole X11, cette option ne fonctionnera pas toujours dans certaines applications. - - - - - - - - {{10, 33}, {536, 267}} - - Presse-papiers - - - - - - 2 - - - - 256 - - - - 256 - {{67, 235}, {402, 18}} - - YES - - 67239424 - 0 - Activation des fenêtres inactives en un clic - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{75, 198}, {385, 31}} - - YES - - 67239424 - 4194304 - En cas d’activation de cette option, si vous cliquez sur une fenêtre inactive, celle-ci deviendra active et le clic sera effectif. - - - - - - - - - - 256 - {{67, 174}, {402, 18}} - - YES - - 67239424 - 0 - Activation des fenêtres survolées par la souris - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{75, 140}, {381, 28}} - - YES - - 67239424 - 4194304 - L’activation des fenêtres X11 suit le curseur. Ceci comporte des effets adverses. - - - - - - - - - - 256 - {{67, 116}, {402, 18}} - - YES - - 67239424 - 0 - Activation des nouvelles fenêtres - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{75, 68}, {385, 42}} - - YES - - 67239424 - 4194304 - Lorsque cette option est activée, la création d’une nouvelle fenêtre X11 fait passer X11.app au premier plan (au lieu de Finder.app, Terminal.app, etc.) - - - - - - - - - {{10, 33}, {536, 267}} - - - Fenêtres - - - - - - - 256 - - - - 256 - {{67, 235}, {402, 18}} - - YES - - 67239424 - 0 - Authentifier les connexions - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{67, 158}, {402, 18}} - - YES - - 67239424 - 0 - Autoriser les connexions de clients réseau - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{85, 187}, {385, 42}} - - YES - - 67239424 - 4194304 - Le lancement d’X11 créera des touches de contrôle d’accès Xauthority. Si l’adresse IP du système change, ces touches ne seront plus valides, ce qui risquera d’empêcher le lancement des applications X11. - - - - - - - - - - 256 - {{85, 96}, {385, 56}} - - YES - - 67239424 - 4194304 - En cas d’activation de cette option, « Authentifier les connexions » doit aussi être activée pour garantir la sécurité du système. En cas de désactivation, les connexions à partir d’applications distantes sont interdites. - - - - - - - - - - 256 - {{20, 5}, {404, 14}} - - YES - - 67239424 - 4194304 - Ces options prennent effet au prochain lancement d’X11. - - - - - - - - - {{10, 33}, {536, 267}} - - Sécurité - - - - - - - 0 - YES - YES - - - - - - {582, 329} - - {{0, 0}, {1440, 878}} - {320, 262} - {1.7976931348623157e+308, 1.7976931348623157e+308} - x11_prefs - - - 11 - 2 - {{302, 440}, {548, 271}} - 1350041600 - Menu de l’application X11 - NSPanel - - View - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - {320, 240} - - - 256 - - - - 265 - {{372, 191}, {162, 32}} - - YES - - 67239424 - 137887744 - Dupliquer - - - -2038284033 - 1 - - Helvetica - 13 - 16 - - - - - - 200 - 25 - - - - - 265 - {{372, 159}, {162, 32}} - - YES - - 67239424 - 137887744 - Supprimer - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 274 - - - - 2304 - - - - 256 - {333, 198} - - YES - - - 256 - {333, 17} - - - - - - 256 - {{334, 0}, {16, 17}} - - - - - 155 - 62.730998992919922 - 1000 - - 75628096 - 2048 - Nom - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 338820672 - 1024 - Text Cell - - - - - 3 - MQA - - - - 3 - YES - YES - - - - - 100 - 40 - 1000 - - 75628096 - 2048 - Commande - - - - - - 338820672 - 1024 - Text Cell - - - - - - - 3 - YES - YES - - - - - 69 - 10 - 1000 - - 75628096 - 2048 - Raccourci - - - 6 - System - headerColor - - - - - - 338820672 - 1024 - Text Cell - - LucidaGrande - 12 - 16 - - - - YES - - 6 - System - controlBackgroundColor - - - - - 3 - YES - YES - - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 17 - 1379958784 - - - 1 - -1 - 0 - YES - 0 - - - {{1, 17}, {333, 198}} - - - - - 4 - - - - 256 - {{334, 17}, {15, 198}} - - - _doScroller: - 0.99492380000000002 - - - - 256 - {{1, 215}, {333, 15}} - - 1 - - _doScroller: - 0.97368421052631582 - - - - 2304 - - - - {{1, 0}, {333, 17}} - - - - - 4 - - - - {{20, 20}, {350, 231}} - - - 50 - - - - - QSAAAEEgAABBmAAAQZgAAA - - - - 265 - {{372, 223}, {162, 32}} - - YES - - -2080244224 - 137887744 - Ajouter un élément - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - {548, 271} - - {{0, 0}, {1440, 878}} - {320, 262} - {1.7976931348623157e+308, 1.7976931348623157e+308} - x11_apps - - - Menu - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Applications - - 1048576 - 2147483647 - - - submenuAction: - - Applications - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Personnaliser… - - 1048576 - 2147483647 - - - - - - - - - - - - - - - copy: - - - - 181 - - - - minimize_window: - - - - 202 - - - - close_window: - - - - 205 - - - - zoom_window: - - - - 206 - - - - bring_to_front: - - - - 207 - - - - hideOtherApplications: - - - - 263 - - - - apps_separator - - - - 273 - - - - apps_table - - - - 301 - - - - apps_table_delete: - - - - 303 - - - - apps_table_duplicate: - - - - 304 - - - - apps_table_show: - - - - 308 - - - - apps_table_new: - - - - 311 - - - - prefs_show: - - - - 318 - - - - x11_about_item - - - - 321 - - - - enable_auth - - - - 387 - - - - enable_tcp - - - - 388 - - - - depth - - - - 389 - - - - use_sysbeep - - - - 390 - - - - fake_buttons - - - - 391 - - - - sync_keymap - - - - 392 - - - - enable_keyequivs - - - - 393 - - - - prefs_changed: - - - - 394 - - - - prefs_changed: - - - - 395 - - - - prefs_changed: - - - - 396 - - - - prefs_changed: - - - - 397 - - - - prefs_changed: - - - - 398 - - - - prefs_changed: - - - - 399 - - - - prefs_changed: - - - - 401 - - - - prefs_panel - - - - 402 - - - - x11_help: - - - - 422 - - - - dockMenu - - - - 426 - - - - dock_menu - - - - 428 - - - - delegate - - - - 429 - - - - hide: - - - - 430 - - - - unhideAllApplications: - - - - 431 - - - - orderFrontStandardAboutPanel: - - - - 433 - - - - dock_apps_menu - - - - 530 - - - - dock_window_separator - - - - 531 - - - - apps_table_show: - - - - 534 - - - - next_window: - - - - 539 - - - - previous_window: - - - - 540 - - - - enable_fullscreen - - - - 546 - - - - enable_fullscreen_changed: - - - - 547 - - - - toggle_fullscreen: - - - - 548 - - - - toggle_fullscreen_item - - - - 549 - - - - menu - - - - 300334 - - - - terminate: - - - - 300336 - - - - prefs_changed: - - - - 300389 - - - - prefs_changed: - - - - 300390 - - - - prefs_changed: - - - - 300391 - - - - click_through - - - - 300392 - - - - focus_follows_mouse - - - - 300393 - - - - focus_on_new_window - - - - 300394 - - - - copy_menu_item - - - - 300443 - - - - sync_pasteboard - - - - 300444 - - - - sync_clipboard_to_pasteboard - - - - 300461 - - - - sync_pasteboard_to_clipboard - - - - 300462 - - - - sync_pasteboard_to_primary - - - - 300463 - - - - sync_primary_immediately - - - - 300464 - - - - prefs_changed: - - - - 300465 - - - - prefs_changed: - - - - 300466 - - - - prefs_changed: - - - - 300467 - - - - prefs_changed: - - - - 300468 - - - - prefs_changed: - - - - 300469 - - - - sync_text1 - - - - 300470 - - - - sync_text2 - - - - 300471 - - - - enable_fullscreen_menu - - - - 300474 - - - - prefs_changed: - - - - 300475 - - - - prefs_changed: - - - - 300480 - - - - option_sends_alt - - - - 300481 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - - - - - - - - MainMenu - - - 19 - - - - - - - - 24 - - - - - - - - - - - - - - - 5 - - - - - 23 - - - - - 92 - - - - - 203 - - - - - 204 - - - - - 536 - - - - - 537 - - - - - 538 - - - - - 56 - - - - - - - - 57 - - - - - - - - - - - - - - - - - - - 58 - - - - - 129 - - - - - 131 - - - - - - - - 130 - - - - - 134 - - - - - 136 - - - - - 143 - - - - - 144 - - - - - 145 - - - - - 149 - - - - - 150 - - - - - 544 - - - - - 545 - - - - - 163 - - - - - - - - 169 - - - - - - - - 157 - - - - - 269 - - - - - - - - 270 - - - - - - - - - 272 - - - - - 305 - - - - - 419 - - - - - - - - 420 - - - - - - - - 421 - - - - - 196 - - - X11Controller - - - 244 - - - - - - PrefsPanel - - - 245 - - - - - - - - 348 - - - - - - - - - - - - 349 - - - - - - - - 351 - - - - - - - - - - - - - - - 363 - - - - - - - - 364 - - - - - - - - 365 - - - - - - - - 368 - - - - - - - - 369 - - - - - - - - 370 - - - - - - - - 352 - - - - - - - - 350 - - - - - - - - - - - - - - - 371 - - - - - - - - 372 - - - - - - - - 382 - - - - - - - - 385 - - - - - - - - 386 - - - - - - - - 541 - - - - - - - - 543 - - - - - - - - 353 - - - - - - - - 354 - - - - - - - - - - - - 374 - - - - - - - - 375 - - - - - - - - 376 - - - - - - - - 377 - - - - - - - - 379 - - - - - - - - 285 - - - - - - EditPrograms - - - 286 - - - - - - - - - - - 423 - - - - - - - DockMenu - - - 524 - - - - - 526 - - - - - - - - 527 - - - - - - - - - 532 - - - - - 533 - - - - - 100363 - - - - - 100364 - - - - - 100365 - - - - - 100368 - - - - - 100369 - - - - - 100370 - - - - - 100371 - - - - - 100372 - - - - - 100382 - - - - - - - - 100385 - - - - - 100386 - - - - - 100541 - - - - - 100543 - - - - - 100374 - - - - - 100375 - - - - - 100376 - - - - - 100377 - - - - - 100379 - - - - - 380 - - - - - - - - - - - 435 - - - - - 384 - - - - - 383 - - - - - 381 - - - - - 295 - - - - - - - - - - - 300295 - - - - - 200295 - - - - - 100295 - - - - - 296 - - - - - - - - - - 535 - - - - - - - - 575 - - - - - 298 - - - - - - - - 573 - - - - - 297 - - - - - - - - 574 - - - - - 310 - - - - - - - - 100310 - - - - - 292 - - - - - - - - 100292 - - - - - 293 - - - - - - - - 100293 - - - - - 300337 - - - - - - - - 300338 - - - - - - - - - - - - - 300358 - - - - - - - - 300359 - - - - - - - - 300360 - - - - - 300361 - - - - - 300362 - - - - - - - - 300363 - - - - - 300364 - - - - - - - - 300365 - - - - - 300368 - - - - - - - - 300369 - - - - - 300370 - - - - - - - - 300371 - - - - - 300421 - - - - - - - - 300422 - - - - - - - - - - - - - - - 300423 - - - - - - - - 300424 - - - - - - - - 300440 - - - - - 300441 - - - - - 300447 - - - - - - - - 300450 - - - - - 300451 - - - - - - - - 300452 - - - - - 300453 - - - - - - - - 300454 - - - - - 300455 - - - - - - - - 300456 - - - - - 300457 - - - - - - - - 300458 - - - - - 300459 - - - - - - - - 300460 - - - - - 300472 - - - - - - - - 300473 - - - - - 300476 - - - - - - - - 300477 - - - - - - - - 300478 - - - - - 300479 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{318, 756}, {64, 6}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{176, 789}, {120, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{202, 626}, {154, 153}} - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{242, 669}, {365, 143}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{271, 666}, {301, 153}} - {{575, 463}, {582, 329}} - com.apple.InterfaceBuilder.CocoaPlugin - {{575, 463}, {582, 329}} - - {{184, 290}, {481, 345}} - - - {3.40282e+38, 3.40282e+38} - {320, 240} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{74, 779}, {171, 33}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{100, 746}, {155, 33}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{838, 503}, {548, 271}} - com.apple.InterfaceBuilder.CocoaPlugin - - - {{838, 503}, {548, 271}} - - {{433, 406}, {486, 327}} - - - {3.40282e+38, 3.40282e+38} - {320, 240} - com.apple.InterfaceBuilder.CocoaPlugin - - {{16, 812}, {356, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{67, 819}, {336, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - IBBuiltInLabel-Red - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{274, 290}, {155, 83}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{311, 789}, {128, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{567, 341}, {150, 33}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{717, 331}, {171, 33}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{28, 609}, {290, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{79, 616}, {218, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - - 300481 - - - - - FirstResponder - NSObject - - IBUserSource - - - - - NSFormatter - NSObject - - IBUserSource - - - - - X11Controller - NSObject - - IBUserSource - - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - ../X11.xcodeproj - 3 - - {9, 8} - {7, 2} - {15, 15} - - - + + + + 1040 + 11A289 + 851 + 1094.2 + 521.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 851 + + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + + NSApplication + + + + FirstResponder + + + NSApplication + + + MainMenu + + + + X11 + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + X11 + + + + À propos d’X11 + + 2147483647 + + + + + + Préférences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + + Services + + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Basculer en mode plein écran + a + 1572864 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Masquer X11 + h + 1048576 + 2147483647 + + + 42 + + + + Masquer les autres + h + 1572864 + 2147483647 + + + + + + Tout afficher + + 1048576 + 2147483647 + + + 42 + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quitter X11 + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + Applications + + 1048576 + 2147483647 + + + submenuAction: + + Applications + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Personnaliser… + + 1048576 + 2147483647 + + + + + + + + + Édition + + 1048576 + 2147483647 + + + submenuAction: + + Édition + + + + Copier + c + 1048576 + 2147483647 + + + + + + + + + Fenêtre + + 1048576 + 2147483647 + + + submenuAction: + + Fenêtre + + + + Fermer + w + 1048576 + 2147483647 + + + + + + Placer dans le Dock + m + 1048576 + 2147483647 + + + + + + Réduire/agrandir + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Faire défiler les fenêtres + ` + 1048840 + 2147483647 + + + + + + Faire défiler les fenêtres en sens inverse + ` + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Tout ramener au premier plan + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Aide + + 1048576 + 2147483647 + + + submenuAction: + + Aide + + + + Aide X11 + + 1048576 + 2147483647 + + + + + + + + _NSMainMenu + + + X11Controller + + + 3 + 2 + {{414, 417}, {582, 329}} + 1350041600 + Préférences d’X11 + NSPanel + + View + + + {1.7976931348623157e+308, 1.7976931348623157e+308} + {320, 240} + + + 256 + + + + 256 + {{13, 10}, {556, 313}} + + + + + 1 + + + + 256 + + + + 256 + {{67, 235}, {402, 18}} + + YES + + 67239424 + 0 + Émuler une souris à trois boutons + + LucidaGrande + 13 + 1044 + + + 1211912703 + 2 + + NSImage + NSSwitch + + + NSSwitch + + + + 200 + 25 + + + + + 256 + {{85, 64}, {385, 42}} + + YES + + 67239424 + 4194304 + Quand cette option est activée, les touches équivalentes de la barre des menus peuvent perturber les applications X11 qui utilisent le modificateur d’instructions virtuelles. + + LucidaGrande + 11 + 3100 + + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 256 + {{85, 195}, {385, 34}} + + YES + + 67239424 + 4194304 + TWFpbnRlbmV6IGxhIHRvdWNoZSBPcHRpb24gb3UgQ29tbWFuZGUgZW5mb25jw6llIHRvdXQgZW4gY2xp +cXVhbnQgcG91ciBhY3RpdmVyIGxlIGJvdXRvbiBkcm9pdCBvdSBjZW50cmFsIGRlIGxhIHNvdXJpcy4K +A + + + + + + + + + + 256 + {{67, 112}, {402, 18}} + + YES + + 67239424 + 0 + Activer les touches équivalentes sous X11 + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{85, 136}, {385, 29}} + + YES + + 67239424 + 4194304 + Autorise les modifications du menu d’entrée pour remplacer la disposition des touches du clavier X11. + + + + + + + + + + 256 + {{67, 171}, {402, 18}} + + YES + + 67239424 + 0 + Utiliser la disposition des touches du clavier du système + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{85, 6}, {385, 28}} + + YES + + 67239424 + 4194304 + Une fois activées, les touches option envoient les symboles Alt_L et Alt_R au lieu de Mode_switch. + + + + + + + + + 256 + {{67, 40}, {402, 18}} + + YES + + 67239424 + 0 + Les touches option envoient Alt_L et Alt_R + + + 1211912703 + 2 + + + + + 200 + 25 + + + + {{10, 33}, {536, 267}} + + Entrée + + + + + + 2 + + + + 256 + + + + 256 + {{104, 223}, {128, 26}} + + YES + + -2076049856 + 1024 + + + 109199615 + 1 + + LucidaGrande + 13 + 16 + + + + + + 400 + 75 + + + du moniteur + + 1048576 + 2147483647 + 1 + + + _popUpItemAction: + -1 + + + YES + + + OtherViews + + + + + + 256 couleurs + + 1048576 + 2147483647 + + + _popUpItemAction: + 8 + + + + + milliers + + 1048576 + 2147483647 + + + _popUpItemAction: + 15 + + + + + millions + + 1048576 + 2147483647 + + + _popUpItemAction: + 24 + + + + + 3 + YES + YES + 1 + + + + + 256 + {{33, 226}, {71, 20}} + + YES + + 67239424 + 4194304 + Couleurs : + + + + + + + + + + 256 + {{52, 204}, {392, 14}} + + YES + + 67239424 + 4194304 + Cette option prend effet au prochain lancement d’X11. + + + + + + + + + + 256 + {{34, 170}, {409, 23}} + + YES + + 67239424 + 0 + Mode plein écran + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{53, 109}, {445, 18}} + + YES + + 67239424 + 0 + Afficher automatiquement la barre des menus en mode plein écran + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{52, 133}, {385, 31}} + + YES + + 67239424 + 4194304 + Active la fenêtre root X11. Utilisez le raccourci clavier Commande + Option + A pour ouvrir et fermer le mode plein écran. + + + + + + + + + {{10, 33}, {536, 267}} + + + Sortie + + + + + + 2 + + + + 256 + + + + 256 + {{25, 235}, {409, 23}} + + YES + + 67239424 + 0 + Activer la synchronisation + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{43, 187}, {378, 42}} + + YES + + 67239424 + 4194304 + Active la commande de menu « Copier » et permet la synchronisation entre le presse-papiers de OSX, celui de X11 (CLIPBOARD) et les mémoires tampons principales (PRIMARY). + + + + + + + + + 256 + {{41, 105}, {424, 18}} + + YES + + 67239424 + 0 + Mettre à jour CLIPBOARD lorsque le presse-papiers est modifié + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{41, 83}, {489, 18}} + + YES + + 67239424 + 0 + Mettre à jour PRIMARY (clic central) lorsque le presse-papiers est modifié + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{41, 61}, {437, 18}} + + YES + + 67239424 + 0 + Mettre à jour le presse-papiers dès la sélection de nouveau texte + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{41, 163}, {424, 18}} + + YES + + 67239424 + 0 + Mettre à jour le presse-papiers lorsque CLIPBOARD est modifié + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{55, 129}, {385, 28}} + + YES + + 67239424 + 4194304 + Désactivez cette option si vous voulez utiliser xclipboard, klipper, ou tout autre gestionnaire de presse-papiers X11. + + + + + + + + + 256 + {{55, 29}, {385, 28}} + + YES + + 67239424 + 4194304 + En raison de limitations du protocole X11, cette option ne fonctionnera pas toujours dans certaines applications. + + + + + + + + {{10, 33}, {536, 267}} + + Presse-papiers + + + + + + 2 + + + + 256 + + + + 256 + {{67, 235}, {402, 18}} + + YES + + 67239424 + 0 + Activation des fenêtres inactives en un clic + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{75, 198}, {385, 31}} + + YES + + 67239424 + 4194304 + En cas d’activation de cette option, si vous cliquez sur une fenêtre inactive, celle-ci deviendra active et le clic sera effectif. + + + + + + + + + + 256 + {{67, 174}, {402, 18}} + + YES + + 67239424 + 0 + Activation des fenêtres survolées par la souris + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{75, 140}, {381, 28}} + + YES + + 67239424 + 4194304 + L’activation des fenêtres X11 suit le curseur. Ceci comporte des effets adverses. + + + + + + + + + + 256 + {{67, 116}, {402, 18}} + + YES + + 67239424 + 0 + Activation des nouvelles fenêtres + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{75, 68}, {385, 42}} + + YES + + 67239424 + 4194304 + Lorsque cette option est activée, la création d’une nouvelle fenêtre X11 fait passer X11.app au premier plan (au lieu de Finder.app, Terminal.app, etc.) + + + + + + + + + {{10, 33}, {536, 267}} + + Fenêtres + + + + + + + 256 + + + + 256 + {{67, 235}, {402, 18}} + + YES + + 67239424 + 0 + Authentifier les connexions + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{67, 158}, {402, 18}} + + YES + + 67239424 + 0 + Autoriser les connexions de clients réseau + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 256 + {{85, 187}, {385, 42}} + + YES + + 67239424 + 4194304 + Le lancement d’X11 créera des touches de contrôle d’accès Xauthority. Si l’adresse IP du système change, ces touches ne seront plus valides, ce qui risquera d’empêcher le lancement des applications X11. + + + + + + + + + + 256 + {{85, 96}, {385, 56}} + + YES + + 67239424 + 4194304 + En cas d’activation de cette option, « Authentifier les connexions » doit aussi être activée pour garantir la sécurité du système. En cas de désactivation, les connexions à partir d’applications distantes sont interdites. + + + + + + + + + + 256 + {{20, 5}, {404, 14}} + + YES + + 67239424 + 4194304 + Ces options prennent effet au prochain lancement d’X11. + + + + + + + + + {{10, 33}, {536, 267}} + + Sécurité + + + + + + + 0 + YES + YES + + + + + + {582, 329} + + {{0, 0}, {1440, 878}} + {320, 262} + {1.7976931348623157e+308, 1.7976931348623157e+308} + x11_prefs + + + 11 + 2 + {{302, 440}, {548, 271}} + 1350041600 + Menu de l’application X11 + NSPanel + + View + + + {1.7976931348623157e+308, 1.7976931348623157e+308} + {320, 240} + + + 256 + + + + 265 + {{372, 191}, {162, 32}} + + YES + + 67239424 + 137887744 + Dupliquer + + + -2038284033 + 1 + + Helvetica + 13 + 16 + + + + + + 200 + 25 + + + + + 265 + {{372, 159}, {162, 32}} + + YES + + 67239424 + 137887744 + Supprimer + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + + 274 + + + + 2304 + + + + 256 + {333, 198} + + YES + + + 256 + {333, 17} + + + + + + 256 + {{334, 0}, {16, 17}} + + + + + 155 + 62.730998992919922 + 1000 + + 75628096 + 2048 + Nom + + + 3 + MC4zMzMzMzI5OQA + + + 6 + System + headerTextColor + + + + + 338820672 + 1024 + Text Cell + + + + + 3 + MQA + + + + 3 + YES + YES + + + + + 100 + 40 + 1000 + + 75628096 + 2048 + Commande + + + + + + 338820672 + 1024 + Text Cell + + + + + + + 3 + YES + YES + + + + + 69 + 10 + 1000 + + 75628096 + 2048 + Raccourci + + + 6 + System + headerColor + + + + + + 338820672 + 1024 + Text Cell + + LucidaGrande + 12 + 16 + + + + YES + + 6 + System + controlBackgroundColor + + + + + 3 + YES + YES + + + + + 3 + 2 + + + 6 + System + gridColor + + 3 + MC41AA + + + 17 + 1379958784 + + + 1 + -1 + 0 + YES + 0 + 1 + + + {{1, 17}, {333, 198}} + + + + + 4 + + + + 256 + {{334, 17}, {15, 198}} + + + _doScroller: + 0.99492380000000002 + + + + 256 + {{1, 215}, {333, 15}} + + 1 + + _doScroller: + 0.68852460000000004 + + + + 2304 + + + + {{1, 0}, {333, 17}} + + + + + 4 + + + + {{20, 20}, {350, 231}} + + + 133170 + + + + + + QSAAAEEgAABBmAAAQZgAAA + + + + 265 + {{372, 223}, {162, 32}} + + YES + + -2080244224 + 137887744 + Ajouter un élément + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + {548, 271} + + {{0, 0}, {1440, 878}} + {320, 262} + {1.7976931348623157e+308, 1.7976931348623157e+308} + x11_apps + + + Menu + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Applications + + 1048576 + 2147483647 + + + submenuAction: + + Applications + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Personnaliser… + + 1048576 + 2147483647 + + + + + + + + + + + + + + + copy: + + + + 181 + + + + minimize_window: + + + + 202 + + + + close_window: + + + + 205 + + + + zoom_window: + + + + 206 + + + + bring_to_front: + + + + 207 + + + + hideOtherApplications: + + + + 263 + + + + apps_separator + + + + 273 + + + + apps_table + + + + 301 + + + + apps_table_delete: + + + + 303 + + + + apps_table_duplicate: + + + + 304 + + + + apps_table_show: + + + + 308 + + + + apps_table_new: + + + + 311 + + + + prefs_show: + + + + 318 + + + + x11_about_item + + + + 321 + + + + enable_auth + + + + 387 + + + + enable_tcp + + + + 388 + + + + depth + + + + 389 + + + + fake_buttons + + + + 391 + + + + sync_keymap + + + + 392 + + + + enable_keyequivs + + + + 393 + + + + prefs_changed: + + + + 394 + + + + prefs_changed: + + + + 395 + + + + prefs_changed: + + + + 396 + + + + prefs_changed: + + + + 398 + + + + prefs_changed: + + + + 399 + + + + prefs_changed: + + + + 401 + + + + prefs_panel + + + + 402 + + + + x11_help: + + + + 422 + + + + dockMenu + + + + 426 + + + + dock_menu + + + + 428 + + + + delegate + + + + 429 + + + + hide: + + + + 430 + + + + unhideAllApplications: + + + + 431 + + + + orderFrontStandardAboutPanel: + + + + 433 + + + + dock_apps_menu + + + + 530 + + + + dock_window_separator + + + + 531 + + + + apps_table_show: + + + + 534 + + + + next_window: + + + + 539 + + + + previous_window: + + + + 540 + + + + enable_fullscreen + + + + 546 + + + + enable_fullscreen_changed: + + + + 547 + + + + toggle_fullscreen: + + + + 548 + + + + toggle_fullscreen_item + + + + 549 + + + + menu + + + + 300334 + + + + terminate: + + + + 300336 + + + + prefs_changed: + + + + 300389 + + + + prefs_changed: + + + + 300390 + + + + prefs_changed: + + + + 300391 + + + + click_through + + + + 300392 + + + + focus_follows_mouse + + + + 300393 + + + + focus_on_new_window + + + + 300394 + + + + copy_menu_item + + + + 300443 + + + + sync_pasteboard + + + + 300444 + + + + sync_clipboard_to_pasteboard + + + + 300461 + + + + sync_pasteboard_to_clipboard + + + + 300462 + + + + sync_pasteboard_to_primary + + + + 300463 + + + + sync_primary_immediately + + + + 300464 + + + + prefs_changed: + + + + 300465 + + + + prefs_changed: + + + + 300466 + + + + prefs_changed: + + + + 300467 + + + + prefs_changed: + + + + 300468 + + + + prefs_changed: + + + + 300469 + + + + sync_text1 + + + + 300470 + + + + sync_text2 + + + + 300471 + + + + enable_fullscreen_menu + + + + 300474 + + + + prefs_changed: + + + + 300475 + + + + prefs_changed: + + + + 300480 + + + + option_sends_alt + + + + 300481 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + MainMenu + + + 19 + + + + + + + + 24 + + + + + + + + + + + + + + + 5 + + + + + 23 + + + + + 92 + + + + + 203 + + + + + 204 + + + + + 536 + + + + + 537 + + + + + 538 + + + + + 56 + + + + + + + + 57 + + + + + + + + + + + + + + + + + + + 58 + + + + + 129 + + + + + 131 + + + + + + + + 130 + + + + + 134 + + + + + 136 + + + + + 143 + + + + + 144 + + + + + 145 + + + + + 149 + + + + + 150 + + + + + 544 + + + + + 545 + + + + + 163 + + + + + + + + 169 + + + + + + + + 157 + + + + + 269 + + + + + + + + 270 + + + + + + + + + 272 + + + + + 305 + + + + + 419 + + + + + + + + 420 + + + + + + + + 421 + + + + + 196 + + + X11Controller + + + 244 + + + + + + PrefsPanel + + + 245 + + + + + + + + 348 + + + + + + + + + + + + 349 + + + + + + + + 351 + + + + + + + + + + + + + + + 363 + + + + + + + + 364 + + + + + + + + 365 + + + + + + + + 368 + + + + + + + + 369 + + + + + + + + 370 + + + + + + + + 352 + + + + + + + + 350 + + + + + + + + + + + + + 382 + + + + + + + + 385 + + + + + + + + 386 + + + + + + + + 541 + + + + + + + + 543 + + + + + + + + 353 + + + + + + + + 354 + + + + + + + + + + + + 374 + + + + + + + + 375 + + + + + + + + 376 + + + + + + + + 377 + + + + + + + + 379 + + + + + + + + 285 + + + + + + EditPrograms + + + 286 + + + + + + + + + + + 423 + + + + + + + DockMenu + + + 524 + + + + + 526 + + + + + + + + 527 + + + + + + + + + 532 + + + + + 533 + + + + + 100363 + + + + + 100364 + + + + + 100365 + + + + + 100368 + + + + + 100369 + + + + + 100370 + + + + + 100382 + + + + + + + + 100385 + + + + + 100386 + + + + + 100541 + + + + + 100543 + + + + + 100374 + + + + + 100375 + + + + + 100376 + + + + + 100377 + + + + + 100379 + + + + + 380 + + + + + + + + + + + 435 + + + + + 384 + + + + + 383 + + + + + 381 + + + + + 295 + + + + + + + + + + + 300295 + + + + + 200295 + + + + + 100295 + + + + + 296 + + + + + + + + + + 535 + + + + + + + + 575 + + + + + 298 + + + + + + + + 573 + + + + + 297 + + + + + + + + 574 + + + + + 310 + + + + + + + + 100310 + + + + + 292 + + + + + + + + 100292 + + + + + 293 + + + + + + + + 100293 + + + + + 300337 + + + + + + + + 300338 + + + + + + + + + + + + + 300358 + + + + + + + + 300359 + + + + + + + + 300360 + + + + + 300361 + + + + + 300362 + + + + + + + + 300363 + + + + + 300364 + + + + + + + + 300365 + + + + + 300368 + + + + + + + + 300369 + + + + + 300370 + + + + + + + + 300371 + + + + + 300421 + + + + + + + + 300422 + + + + + + + + + + + + + + + 300423 + + + + + + + + 300424 + + + + + + + + 300440 + + + + + 300441 + + + + + 300447 + + + + + + + + 300450 + + + + + 300451 + + + + + + + + 300452 + + + + + 300453 + + + + + + + + 300454 + + + + + 300455 + + + + + + + + 300456 + + + + + 300457 + + + + + + + + 300458 + + + + + 300459 + + + + + + + + 300460 + + + + + 300472 + + + + + + + + 300473 + + + + + 300476 + + + + + + + + 300477 + + + + + + + + 300478 + + + + + 300479 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{168, 821}, {113, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{202, 626}, {154, 153}} + com.apple.InterfaceBuilder.CocoaPlugin + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{349, 868}, {315, 143}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{271, 666}, {301, 153}} + {{507, 565}, {484, 308}} + com.apple.InterfaceBuilder.CocoaPlugin + {{507, 565}, {484, 308}} + + {{184, 290}, {481, 345}} + + + {3.40282e+38, 3.40282e+38} + {320, 240} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{58, 803}, {155, 33}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{100, 746}, {155, 33}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{68, 585}, {454, 271}} + com.apple.InterfaceBuilder.CocoaPlugin + + + {{68, 585}, {454, 271}} + + {{433, 406}, {486, 327}} + + + {3.40282e+38, 3.40282e+38} + {320, 240} + com.apple.InterfaceBuilder.CocoaPlugin + + {{145, 1011}, {336, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{67, 819}, {336, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{20, 641}, {218, 203}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{79, 616}, {218, 203}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + + 300481 + + + + + FirstResponder + NSObject + + IBUserSource + + + + + NSFormatter + NSObject + + IBUserSource + + + + + X11Controller + NSObject + + IBUserSource + + + + + + + X11Controller + NSObject + + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + + + + apps_table_delete: + id + + + apps_table_done: + id + + + apps_table_duplicate: + id + + + apps_table_new: + id + + + apps_table_show: + id + + + bring_to_front: + id + + + close_window: + id + + + enable_fullscreen_changed: + id + + + minimize_window: + id + + + next_window: + id + + + prefs_changed: + id + + + prefs_show: + id + + + previous_window: + id + + + quit: + id + + + toggle_fullscreen: + id + + + x11_help: + id + + + zoom_window: + id + + + + NSMenuItem + NSTableView + NSButton + NSMenuItem + NSPopUpButton + NSMenu + NSMenu + NSMenuItem + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSPanel + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSTextField + NSTextField + NSMenuItem + NSButton + NSMenuItem + NSMenuItem + + + + apps_separator + NSMenuItem + + + apps_table + NSTableView + + + click_through + NSButton + + + copy_menu_item + NSMenuItem + + + depth + NSPopUpButton + + + dock_apps_menu + NSMenu + + + dock_menu + NSMenu + + + dock_window_separator + NSMenuItem + + + enable_auth + NSButton + + + enable_fullscreen + NSButton + + + enable_fullscreen_menu + NSButton + + + enable_keyequivs + NSButton + + + enable_tcp + NSButton + + + fake_buttons + NSButton + + + focus_follows_mouse + NSButton + + + focus_on_new_window + NSButton + + + option_sends_alt + NSButton + + + prefs_panel + NSPanel + + + sync_clipboard_to_pasteboard + NSButton + + + sync_keymap + NSButton + + + sync_pasteboard + NSButton + + + sync_pasteboard_to_clipboard + NSButton + + + sync_pasteboard_to_primary + NSButton + + + sync_primary_immediately + NSButton + + + sync_text1 + NSTextField + + + sync_text2 + NSTextField + + + toggle_fullscreen_item + NSMenuItem + + + use_sysbeep + NSButton + + + window_separator + NSMenuItem + + + x11_about_item + NSMenuItem + + + + IBDocumentRelativeSource + ../../../X11Controller.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + YES + ../X11.xcodeproj + 3 + + {9, 8} + {7, 2} + {15, 15} + + + diff --git a/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/keyedobjects.nib b/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/keyedobjects.nib index 981332331..3443780f1 100644 Binary files a/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/keyedobjects.nib and b/xorg-server/hw/xquartz/bundle/Resources/French.lproj/main.nib/keyedobjects.nib differ diff --git a/xorg-server/hw/xquartz/bundle/Resources/German.lproj/locversion.plist b/xorg-server/hw/xquartz/bundle/Resources/German.lproj/locversion.plist index 313b57752..caf0364c7 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/German.lproj/locversion.plist +++ b/xorg-server/hw/xquartz/bundle/Resources/German.lproj/locversion.plist @@ -3,12 +3,12 @@ LprojCompatibleVersion - 101 + 102 LprojLocale de LprojRevisionLevel 1 LprojVersion - 101 + 102 diff --git a/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/designable.nib b/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/designable.nib index d34ff7266..dea837bce 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/designable.nib +++ b/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/designable.nib @@ -2,13 +2,13 @@ 1040 - 11A194b - 787 - 1079 - 502.00 + 11A289 + 844 + 1094.2 + 521.00 com.apple.InterfaceBuilder.CocoaPlugin - 787 + 844 @@ -370,7 +370,7 @@ View - {3.4028235e+38, 3.4028235e+38} + {1.7976931348623157e+308, 1.7976931348623157e+308} {320, 240} @@ -387,7 +387,7 @@ 1 - + 256 @@ -408,7 +408,7 @@ 1211912703 2 - + NSImage NSSwitch @@ -444,7 +444,7 @@ controlColor 3 - MC42NjY2NjY2ODY1AA + MC42NjY2NjY2NjY3AA @@ -491,7 +491,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -530,7 +530,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -568,7 +568,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -578,7 +578,6 @@ dmllcmVuLgo {{10, 33}, {559, 240}} - Eingabe @@ -589,7 +588,7 @@ dmllcmVuLgo 2 - + 256 @@ -616,16 +615,17 @@ dmllcmVuLgo 400 75 - + - 16,7 Millionen Farben + Vom Monitor 1048576 2147483647 + 1 _popUpItemAction: - 24 + -1 YES @@ -634,47 +634,45 @@ dmllcmVuLgo OtherViews - + + - Vom Monitor + 256 Farben 1048576 2147483647 - 1 _popUpItemAction: - -1 + 8 - + - 256 Farben + 32768 Farben 1048576 2147483647 _popUpItemAction: - 8 + 15 - + - 32768 Farben + 16,7 Millionen Farben 1048576 2147483647 _popUpItemAction: - 15 + 24 - - 3 3 YES YES @@ -729,7 +727,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -751,7 +749,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -778,6 +776,7 @@ dmllcmVuLgo {{10, 33}, {559, 240}} + Ausgabe @@ -805,7 +804,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -843,7 +842,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -865,7 +864,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -887,7 +886,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -909,7 +908,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -978,7 +977,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -1016,7 +1015,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -1054,7 +1053,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -1104,7 +1103,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -1126,7 +1125,7 @@ dmllcmVuLgo 1211912703 2 - + @@ -1193,13 +1192,13 @@ dmllcmVuLgo - + 0 YES YES - + @@ -1207,7 +1206,7 @@ dmllcmVuLgo {{0, 0}, {1440, 878}} {320, 262} - {3.4028235e+38, 3.4028235e+38} + {1.7976931348623157e+308, 1.7976931348623157e+308} x11_prefs @@ -1221,7 +1220,7 @@ dmllcmVuLgo View - {3.4028235e+38, 3.4028235e+38} + {1.7976931348623157e+308, 1.7976931348623157e+308} {512, 240} @@ -1316,7 +1315,7 @@ dmllcmVuLgo 3 - MC4zMzMzMzI5ODU2AA + MC4zMzMzMzI5OQA 6 @@ -1434,6 +1433,7 @@ dmllcmVuLgo 0 YES 0 + 1 {{1, 17}, {301, 198}} @@ -1450,7 +1450,7 @@ dmllcmVuLgo _doScroller: - 0.99492377042770386 + 0.99492380000000002 @@ -1460,7 +1460,7 @@ dmllcmVuLgo 1 _doScroller: - 0.68852460384368896 + 0.68852460000000004 @@ -1480,11 +1480,12 @@ dmllcmVuLgo {{20, 20}, {318, 231}} - 50 + 133170 + QSAAAEEgAABBmAAAQZgAAA @@ -1515,7 +1516,7 @@ dmllcmVuLgo {{0, 0}, {1440, 878}} {512, 262} - {3.4028235e+38, 3.4028235e+38} + {1.7976931348623157e+308, 1.7976931348623157e+308} x11_apps @@ -3235,10 +3236,9 @@ dmllcmVuLgo com.apple.InterfaceBuilder.CocoaPlugin {{271, 666}, {301, 153}} - {{390, 203}, {613, 302}} + {{507, 565}, {484, 308}} com.apple.InterfaceBuilder.CocoaPlugin - - {{390, 203}, {613, 302}} + {{507, 565}, {484, 308}} {{184, 290}, {481, 345}} @@ -3385,7 +3385,6 @@ dmllcmVuLgo com.apple.InterfaceBuilder.CocoaPlugin - {{476, 379}, {215, 83}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3488,6 +3487,259 @@ dmllcmVuLgo + + + X11Controller + NSObject + + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + + + + apps_table_delete: + id + + + apps_table_done: + id + + + apps_table_duplicate: + id + + + apps_table_new: + id + + + apps_table_show: + id + + + bring_to_front: + id + + + close_window: + id + + + enable_fullscreen_changed: + id + + + minimize_window: + id + + + next_window: + id + + + prefs_changed: + id + + + prefs_show: + id + + + previous_window: + id + + + quit: + id + + + toggle_fullscreen: + id + + + x11_help: + id + + + zoom_window: + id + + + + NSMenuItem + NSTableView + NSButton + NSMenuItem + NSPopUpButton + NSMenu + NSMenu + NSMenuItem + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSPanel + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSTextField + NSTextField + NSMenuItem + NSButton + NSMenuItem + NSMenuItem + + + + apps_separator + NSMenuItem + + + apps_table + NSTableView + + + click_through + NSButton + + + copy_menu_item + NSMenuItem + + + depth + NSPopUpButton + + + dock_apps_menu + NSMenu + + + dock_menu + NSMenu + + + dock_window_separator + NSMenuItem + + + enable_auth + NSButton + + + enable_fullscreen + NSButton + + + enable_fullscreen_menu + NSButton + + + enable_keyequivs + NSButton + + + enable_tcp + NSButton + + + fake_buttons + NSButton + + + focus_follows_mouse + NSButton + + + focus_on_new_window + NSButton + + + option_sends_alt + NSButton + + + prefs_panel + NSPanel + + + sync_clipboard_to_pasteboard + NSButton + + + sync_keymap + NSButton + + + sync_pasteboard + NSButton + + + sync_pasteboard_to_clipboard + NSButton + + + sync_pasteboard_to_primary + NSButton + + + sync_primary_immediately + NSButton + + + sync_text1 + NSTextField + + + sync_text2 + NSTextField + + + toggle_fullscreen_item + NSMenuItem + + + use_sysbeep + NSButton + + + window_separator + NSMenuItem + + + x11_about_item + NSMenuItem + + + + IBDocumentRelativeSource + ../../../X11Controller.h + + + 0 IBCocoaFramework diff --git a/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/keyedobjects.nib b/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/keyedobjects.nib index f5df325d4..55b75a38a 100644 Binary files a/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/keyedobjects.nib and b/xorg-server/hw/xquartz/bundle/Resources/German.lproj/main.nib/keyedobjects.nib differ diff --git a/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/locversion.plist b/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/locversion.plist index 0c81bd02a..6c8948397 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/locversion.plist +++ b/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/locversion.plist @@ -3,12 +3,12 @@ LprojCompatibleVersion - 101 + 102 LprojLocale ja LprojRevisionLevel 1 LprojVersion - 101 + 102 diff --git a/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/designable.nib b/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/designable.nib index 2803baa8d..a800d3c9d 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/designable.nib +++ b/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/designable.nib @@ -2,13 +2,13 @@ 1040 - 11A194b - 787 - 1079 - 502.00 + 11A289 + 844 + 1094.2 + 521.00 com.apple.InterfaceBuilder.CocoaPlugin - 787 + 844 @@ -373,7 +373,7 @@ {1.7976931348623157e+308, 1.7976931348623157e+308} {320, 240} - + 256 @@ -381,7 +381,6 @@ 256 {{13, 10}, {558, 292}} - @@ -409,7 +408,7 @@ 1211912703 2 - + NSImage NSSwitch @@ -469,9 +468,9 @@ 67239424 4194304 T3B0aW9uIOOCreODvOOCkuaKvOOBl+OBn+OBvuOBvuOCr+ODquODg+OCr+OBmeOCi+OBqOODnuOCpuOC -ueOBruS4reODnOOCv+ODs+aTjeS9nOOBq+OBquOCiuOAgeOCs+ODnuODs+ODieOCreODvOOCkuaKvOOB -l+OBn+OBvuOBvuOCr+ODquODg+OCr+OBmeOCi+OBqOODnuOCpuOCueOBruWPs+ODnOOCv+ODs+aTjeS9 -nOOBq+OBquOCiuOBvuOBmeOAggo +ueOBruS4reODnOOCv+ODs+aTjeS9nOOBq+OBquOCiuOAgUNvbW1hbmQg44Kt44O844KS5oq844GX44Gf +44G+44G+44Kv44Oq44OD44Kv44GZ44KL44Go44Oe44Km44K544Gu5Y+z44Oc44K/44Oz5pON5L2c44Gr +44Gq44KK44G+44GZ44CCCg @@ -493,7 +492,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -532,7 +531,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -570,7 +569,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -598,7 +597,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 256 {{75, 201}, {163, 26}} - YES -2076049856 @@ -687,7 +685,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 256 {{17, 205}, {56, 19}} - YES 67239424 @@ -705,7 +702,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 256 {{36, 183}, {392, 14}} - YES 67239424 @@ -723,7 +719,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 256 {{18, 149}, {409, 23}} - YES 67239424 @@ -733,7 +728,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -746,7 +741,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 256 {{37, 83}, {409, 23}} - YES 67239424 @@ -756,7 +750,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -769,7 +763,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 256 {{36, 113}, {468, 30}} - YES 67239424 @@ -785,7 +778,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo {{10, 33}, {538, 246}} - 出力 @@ -813,7 +805,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -851,7 +843,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -873,7 +865,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -895,7 +887,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -917,7 +909,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -986,7 +978,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -1025,7 +1017,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -1064,7 +1056,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -1115,7 +1107,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -1137,7 +1129,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 1211912703 2 - + @@ -1215,8 +1207,6 @@ nOOBq+OBquOCiuOBvuOBmeOAggo {584, 308} - - {{0, 0}, {1440, 878}} {320, 262} @@ -1450,6 +1440,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo 0 YES 0 + 1 {{1, 17}, {301, 198}} @@ -1496,7 +1487,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo {{20, 20}, {318, 231}} - 50 + 133170 @@ -3251,10 +3242,9 @@ nOOBq+OBquOCiuOBvuOBmeOAggo com.apple.InterfaceBuilder.CocoaPlugin {{271, 666}, {301, 153}} - {{539, 548}, {584, 308}} + {{507, 565}, {484, 308}} com.apple.InterfaceBuilder.CocoaPlugin - - {{539, 548}, {584, 308}} + {{507, 565}, {484, 308}} {{184, 290}, {481, 345}} @@ -3284,7 +3274,7 @@ nOOBq+OBquOCiuOBvuOBmeOAggo {454, 271} com.apple.InterfaceBuilder.CocoaPlugin - {{145, 836}, {394, 20}} + {{145, 1011}, {336, 20}} com.apple.InterfaceBuilder.CocoaPlugin {{67, 819}, {336, 20}} @@ -3503,6 +3493,259 @@ nOOBq+OBquOCiuOBvuOBmeOAggo + + + X11Controller + NSObject + + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + + + + apps_table_delete: + id + + + apps_table_done: + id + + + apps_table_duplicate: + id + + + apps_table_new: + id + + + apps_table_show: + id + + + bring_to_front: + id + + + close_window: + id + + + enable_fullscreen_changed: + id + + + minimize_window: + id + + + next_window: + id + + + prefs_changed: + id + + + prefs_show: + id + + + previous_window: + id + + + quit: + id + + + toggle_fullscreen: + id + + + x11_help: + id + + + zoom_window: + id + + + + NSMenuItem + NSTableView + NSButton + NSMenuItem + NSPopUpButton + NSMenu + NSMenu + NSMenuItem + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSPanel + NSButton + NSButton + NSButton + NSButton + NSButton + NSButton + NSTextField + NSTextField + NSMenuItem + NSButton + NSMenuItem + NSMenuItem + + + + apps_separator + NSMenuItem + + + apps_table + NSTableView + + + click_through + NSButton + + + copy_menu_item + NSMenuItem + + + depth + NSPopUpButton + + + dock_apps_menu + NSMenu + + + dock_menu + NSMenu + + + dock_window_separator + NSMenuItem + + + enable_auth + NSButton + + + enable_fullscreen + NSButton + + + enable_fullscreen_menu + NSButton + + + enable_keyequivs + NSButton + + + enable_tcp + NSButton + + + fake_buttons + NSButton + + + focus_follows_mouse + NSButton + + + focus_on_new_window + NSButton + + + option_sends_alt + NSButton + + + prefs_panel + NSPanel + + + sync_clipboard_to_pasteboard + NSButton + + + sync_keymap + NSButton + + + sync_pasteboard + NSButton + + + sync_pasteboard_to_clipboard + NSButton + + + sync_pasteboard_to_primary + NSButton + + + sync_primary_immediately + NSButton + + + sync_text1 + NSTextField + + + sync_text2 + NSTextField + + + toggle_fullscreen_item + NSMenuItem + + + use_sysbeep + NSButton + + + window_separator + NSMenuItem + + + x11_about_item + NSMenuItem + + + + IBDocumentRelativeSource + ../../../X11Controller.h + + + 0 IBCocoaFramework diff --git a/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/keyedobjects.nib b/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/keyedobjects.nib index 46d376334..6700f64a6 100644 Binary files a/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/keyedobjects.nib and b/xorg-server/hw/xquartz/bundle/Resources/Japanese.lproj/main.nib/keyedobjects.nib differ -- cgit v1.2.3