midbe.c revision 05b261ec
105b261ecSmrg/****************************************************************************** 205b261ecSmrg * 305b261ecSmrg * Copyright (c) 1994, 1995 Hewlett-Packard Company 405b261ecSmrg * 505b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining 605b261ecSmrg * a copy of this software and associated documentation files (the 705b261ecSmrg * "Software"), to deal in the Software without restriction, including 805b261ecSmrg * without limitation the rights to use, copy, modify, merge, publish, 905b261ecSmrg * distribute, sublicense, and/or sell copies of the Software, and to 1005b261ecSmrg * permit persons to whom the Software is furnished to do so, subject to 1105b261ecSmrg * the following conditions: 1205b261ecSmrg * 1305b261ecSmrg * The above copyright notice and this permission notice shall be included 1405b261ecSmrg * in all copies or substantial portions of the Software. 1505b261ecSmrg * 1605b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1705b261ecSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1805b261ecSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1905b261ecSmrg * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, 2005b261ecSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2105b261ecSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 2205b261ecSmrg * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2305b261ecSmrg * 2405b261ecSmrg * Except as contained in this notice, the name of the Hewlett-Packard 2505b261ecSmrg * Company shall not be used in advertising or otherwise to promote the 2605b261ecSmrg * sale, use or other dealings in this Software without prior written 2705b261ecSmrg * authorization from the Hewlett-Packard Company. 2805b261ecSmrg * 2905b261ecSmrg * Machine-independent DBE code 3005b261ecSmrg * 3105b261ecSmrg *****************************************************************************/ 3205b261ecSmrg 3305b261ecSmrg 3405b261ecSmrg/* INCLUDES */ 3505b261ecSmrg 3605b261ecSmrg#define NEED_REPLIES 3705b261ecSmrg#define NEED_EVENTS 3805b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 3905b261ecSmrg#include <dix-config.h> 4005b261ecSmrg#endif 4105b261ecSmrg 4205b261ecSmrg#include <X11/X.h> 4305b261ecSmrg#include <X11/Xproto.h> 4405b261ecSmrg#include "misc.h" 4505b261ecSmrg#include "os.h" 4605b261ecSmrg#include "windowstr.h" 4705b261ecSmrg#include "scrnintstr.h" 4805b261ecSmrg#include "pixmapstr.h" 4905b261ecSmrg#include "extnsionst.h" 5005b261ecSmrg#include "dixstruct.h" 5105b261ecSmrg#include "resource.h" 5205b261ecSmrg#include "opaque.h" 5305b261ecSmrg#include "dbestruct.h" 5405b261ecSmrg#include "midbestr.h" 5505b261ecSmrg#include "regionstr.h" 5605b261ecSmrg#include "gcstruct.h" 5705b261ecSmrg#include "inputstr.h" 5805b261ecSmrg#include "midbe.h" 5905b261ecSmrg 6005b261ecSmrg#include <stdio.h> 6105b261ecSmrg 6205b261ecSmrgstatic int miDbePrivPrivGeneration = 0; 6305b261ecSmrgstatic int miDbeWindowPrivPrivIndex = -1; 6405b261ecSmrgstatic RESTYPE dbeDrawableResType; 6505b261ecSmrgstatic RESTYPE dbeWindowPrivResType; 6605b261ecSmrgstatic int dbeScreenPrivIndex = -1; 6705b261ecSmrgstatic int dbeWindowPrivIndex = -1; 6805b261ecSmrg 6905b261ecSmrg 7005b261ecSmrg/****************************************************************************** 7105b261ecSmrg * 7205b261ecSmrg * DBE MI Procedure: miDbeGetVisualInfo 7305b261ecSmrg * 7405b261ecSmrg * Description: 7505b261ecSmrg * 7605b261ecSmrg * This is the MI function for the DbeGetVisualInfo request. This function 7705b261ecSmrg * is called through pDbeScreenPriv->GetVisualInfo. This function is also 7805b261ecSmrg * called for the DbeAllocateBackBufferName request at the extension level; 7905b261ecSmrg * it is called by ProcDbeAllocateBackBufferName() in dbe.c. 8005b261ecSmrg * 8105b261ecSmrg * If memory allocation fails or we can not get the visual info, this 8205b261ecSmrg * function returns FALSE. Otherwise, it returns TRUE for success. 8305b261ecSmrg * 8405b261ecSmrg *****************************************************************************/ 8505b261ecSmrg 8605b261ecSmrgstatic Bool 8705b261ecSmrgmiDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo *pScrVisInfo) 8805b261ecSmrg{ 8905b261ecSmrg register int i, j, k; 9005b261ecSmrg register int count; 9105b261ecSmrg DepthPtr pDepth; 9205b261ecSmrg XdbeVisualInfo *visInfo; 9305b261ecSmrg 9405b261ecSmrg 9505b261ecSmrg /* Determine number of visuals for this screen. */ 9605b261ecSmrg for (i = 0, count = 0; i < pScreen->numDepths; i++) 9705b261ecSmrg { 9805b261ecSmrg count += pScreen->allowedDepths[i].numVids; 9905b261ecSmrg } 10005b261ecSmrg 10105b261ecSmrg /* Allocate an array of XdbeVisualInfo items. */ 10205b261ecSmrg if (!(visInfo = (XdbeVisualInfo *)xalloc(count * sizeof(XdbeVisualInfo)))) 10305b261ecSmrg { 10405b261ecSmrg return(FALSE); /* memory alloc failure */ 10505b261ecSmrg } 10605b261ecSmrg 10705b261ecSmrg for (i = 0, k = 0; i < pScreen->numDepths; i++) 10805b261ecSmrg { 10905b261ecSmrg /* For each depth of this screen, get visual information. */ 11005b261ecSmrg 11105b261ecSmrg pDepth = &pScreen->allowedDepths[i]; 11205b261ecSmrg 11305b261ecSmrg for (j = 0; j < pDepth->numVids; j++) 11405b261ecSmrg { 11505b261ecSmrg /* For each visual for this depth of this screen, get visual ID 11605b261ecSmrg * and visual depth. Since this is MI code, we will always return 11705b261ecSmrg * the same performance level for all visuals (0). A higher 11805b261ecSmrg * performance level value indicates higher performance. 11905b261ecSmrg */ 12005b261ecSmrg visInfo[k].visual = pDepth->vids[j]; 12105b261ecSmrg visInfo[k].depth = pDepth->depth; 12205b261ecSmrg visInfo[k].perflevel = 0; 12305b261ecSmrg k++; 12405b261ecSmrg } 12505b261ecSmrg } 12605b261ecSmrg 12705b261ecSmrg /* Record the number of visuals and point visual_depth to 12805b261ecSmrg * the array of visual info. 12905b261ecSmrg */ 13005b261ecSmrg pScrVisInfo->count = count; 13105b261ecSmrg pScrVisInfo->visinfo = visInfo; 13205b261ecSmrg 13305b261ecSmrg return(TRUE); /* success */ 13405b261ecSmrg 13505b261ecSmrg} /* miDbeGetVisualInfo() */ 13605b261ecSmrg 13705b261ecSmrg 13805b261ecSmrg/****************************************************************************** 13905b261ecSmrg * 14005b261ecSmrg * DBE MI Procedure: miAllocBackBufferName 14105b261ecSmrg * 14205b261ecSmrg * Description: 14305b261ecSmrg * 14405b261ecSmrg * This is the MI function for the DbeAllocateBackBufferName request. 14505b261ecSmrg * 14605b261ecSmrg *****************************************************************************/ 14705b261ecSmrg 14805b261ecSmrgstatic int 14905b261ecSmrgmiDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction) 15005b261ecSmrg{ 15105b261ecSmrg ScreenPtr pScreen; 15205b261ecSmrg DbeWindowPrivPtr pDbeWindowPriv; 15305b261ecSmrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 15405b261ecSmrg DbeScreenPrivPtr pDbeScreenPriv; 15505b261ecSmrg GCPtr pGC; 15605b261ecSmrg xRectangle clearRect; 15705b261ecSmrg 15805b261ecSmrg 15905b261ecSmrg pScreen = pWin->drawable.pScreen; 16005b261ecSmrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 16105b261ecSmrg 16205b261ecSmrg if (pDbeWindowPriv->nBufferIDs == 0) 16305b261ecSmrg { 16405b261ecSmrg /* There is no buffer associated with the window. 16505b261ecSmrg * We have to create the window priv priv. Remember, the window 16605b261ecSmrg * priv was created at the DIX level, so all we need to do is 16705b261ecSmrg * create the priv priv and attach it to the priv. 16805b261ecSmrg */ 16905b261ecSmrg 17005b261ecSmrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 17105b261ecSmrg 17205b261ecSmrg /* Setup the window priv priv. */ 17305b261ecSmrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 17405b261ecSmrg pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv; 17505b261ecSmrg 17605b261ecSmrg /* Get a front pixmap. */ 17705b261ecSmrg if (!(pDbeWindowPrivPriv->pFrontBuffer = 17805b261ecSmrg (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, 17905b261ecSmrg pDbeWindowPriv->height, 18005b261ecSmrg pWin->drawable.depth))) 18105b261ecSmrg { 18205b261ecSmrg return(BadAlloc); 18305b261ecSmrg } 18405b261ecSmrg 18505b261ecSmrg /* Get a back pixmap. */ 18605b261ecSmrg if (!(pDbeWindowPrivPriv->pBackBuffer = 18705b261ecSmrg (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, 18805b261ecSmrg pDbeWindowPriv->height, 18905b261ecSmrg pWin->drawable.depth))) 19005b261ecSmrg { 19105b261ecSmrg (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); 19205b261ecSmrg return(BadAlloc); 19305b261ecSmrg } 19405b261ecSmrg 19505b261ecSmrg 19605b261ecSmrg /* Make the back pixmap a DBE drawable resource. */ 19705b261ecSmrg if (!AddResource(bufId, dbeDrawableResType, 19805b261ecSmrg (pointer)pDbeWindowPrivPriv->pBackBuffer)) 19905b261ecSmrg { 20005b261ecSmrg /* free the buffer and the drawable resource */ 20105b261ecSmrg FreeResource(bufId, RT_NONE); 20205b261ecSmrg return(BadAlloc); 20305b261ecSmrg } 20405b261ecSmrg 20505b261ecSmrg 20605b261ecSmrg /* Attach the priv priv to the priv. */ 20705b261ecSmrg pDbeWindowPriv->devPrivates[miDbeWindowPrivPrivIndex].ptr = 20805b261ecSmrg (pointer)pDbeWindowPrivPriv; 20905b261ecSmrg 21005b261ecSmrg 21105b261ecSmrg /* Clear the back buffer. */ 21205b261ecSmrg pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 21305b261ecSmrg if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) 21405b261ecSmrg { 21505b261ecSmrg ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC); 21605b261ecSmrg clearRect.x = clearRect.y = 0; 21705b261ecSmrg clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width; 21805b261ecSmrg clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height; 21905b261ecSmrg (*pGC->ops->PolyFillRect)( 22005b261ecSmrg (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1, 22105b261ecSmrg &clearRect); 22205b261ecSmrg } 22305b261ecSmrg FreeScratchGC(pGC); 22405b261ecSmrg 22505b261ecSmrg } /* if no buffer associated with the window */ 22605b261ecSmrg 22705b261ecSmrg else 22805b261ecSmrg { 22905b261ecSmrg /* A buffer is already associated with the window. 23005b261ecSmrg * Place the new buffer ID information at the head of the ID list. 23105b261ecSmrg */ 23205b261ecSmrg 23305b261ecSmrg /* Associate the new ID with an existing pixmap. */ 23405b261ecSmrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 23505b261ecSmrg if (!AddResource(bufId, dbeDrawableResType, 23605b261ecSmrg (pointer)pDbeWindowPrivPriv->pBackBuffer)) 23705b261ecSmrg { 23805b261ecSmrg return(BadAlloc); 23905b261ecSmrg } 24005b261ecSmrg 24105b261ecSmrg } 24205b261ecSmrg 24305b261ecSmrg return(Success); 24405b261ecSmrg 24505b261ecSmrg} /* miDbeAllocBackBufferName() */ 24605b261ecSmrg 24705b261ecSmrg 24805b261ecSmrg/****************************************************************************** 24905b261ecSmrg * 25005b261ecSmrg * DBE MI Procedure: miDbeAliasBuffers 25105b261ecSmrg * 25205b261ecSmrg * Description: 25305b261ecSmrg * 25405b261ecSmrg * This function associates all XIDs of a buffer with the back pixmap 25505b261ecSmrg * stored in the window priv. 25605b261ecSmrg * 25705b261ecSmrg *****************************************************************************/ 25805b261ecSmrg 25905b261ecSmrgstatic void 26005b261ecSmrgmiDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv) 26105b261ecSmrg{ 26205b261ecSmrg int i; 26305b261ecSmrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv = 26405b261ecSmrg MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 26505b261ecSmrg 26605b261ecSmrg for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) 26705b261ecSmrg { 26805b261ecSmrg ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, 26905b261ecSmrg (pointer)pDbeWindowPrivPriv->pBackBuffer); 27005b261ecSmrg } 27105b261ecSmrg 27205b261ecSmrg} /* miDbeAliasBuffers() */ 27305b261ecSmrg 27405b261ecSmrg 27505b261ecSmrg/****************************************************************************** 27605b261ecSmrg * 27705b261ecSmrg * DBE MI Procedure: miDbeSwapBuffers 27805b261ecSmrg * 27905b261ecSmrg * Description: 28005b261ecSmrg * 28105b261ecSmrg * This is the MI function for the DbeSwapBuffers request. 28205b261ecSmrg * 28305b261ecSmrg *****************************************************************************/ 28405b261ecSmrg 28505b261ecSmrgstatic int 28605b261ecSmrgmiDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo) 28705b261ecSmrg{ 28805b261ecSmrg DbeScreenPrivPtr pDbeScreenPriv; 28905b261ecSmrg GCPtr pGC; 29005b261ecSmrg WindowPtr pWin; 29105b261ecSmrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 29205b261ecSmrg PixmapPtr pTmpBuffer; 29305b261ecSmrg xRectangle clearRect; 29405b261ecSmrg 29505b261ecSmrg 29605b261ecSmrg pWin = swapInfo[0].pWindow; 29705b261ecSmrg pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); 29805b261ecSmrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin); 29905b261ecSmrg pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 30005b261ecSmrg 30105b261ecSmrg /* 30205b261ecSmrg ********************************************************************** 30305b261ecSmrg ** Setup before swap. 30405b261ecSmrg ********************************************************************** 30505b261ecSmrg */ 30605b261ecSmrg 30705b261ecSmrg switch(swapInfo[0].swapAction) 30805b261ecSmrg { 30905b261ecSmrg case XdbeUndefined: 31005b261ecSmrg break; 31105b261ecSmrg 31205b261ecSmrg case XdbeBackground: 31305b261ecSmrg break; 31405b261ecSmrg 31505b261ecSmrg case XdbeUntouched: 31605b261ecSmrg ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC); 31705b261ecSmrg (*pGC->ops->CopyArea)((DrawablePtr)pWin, 31805b261ecSmrg (DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, 31905b261ecSmrg pGC, 0, 0, pWin->drawable.width, 32005b261ecSmrg pWin->drawable.height, 0, 0); 32105b261ecSmrg break; 32205b261ecSmrg 32305b261ecSmrg case XdbeCopied: 32405b261ecSmrg break; 32505b261ecSmrg 32605b261ecSmrg } 32705b261ecSmrg 32805b261ecSmrg /* 32905b261ecSmrg ********************************************************************** 33005b261ecSmrg ** Swap. 33105b261ecSmrg ********************************************************************** 33205b261ecSmrg */ 33305b261ecSmrg 33405b261ecSmrg ValidateGC((DrawablePtr)pWin, pGC); 33505b261ecSmrg (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, 33605b261ecSmrg (DrawablePtr)pWin, pGC, 0, 0, 33705b261ecSmrg pWin->drawable.width, pWin->drawable.height, 33805b261ecSmrg 0, 0); 33905b261ecSmrg 34005b261ecSmrg /* 34105b261ecSmrg ********************************************************************** 34205b261ecSmrg ** Tasks after swap. 34305b261ecSmrg ********************************************************************** 34405b261ecSmrg */ 34505b261ecSmrg 34605b261ecSmrg switch(swapInfo[0].swapAction) 34705b261ecSmrg { 34805b261ecSmrg case XdbeUndefined: 34905b261ecSmrg break; 35005b261ecSmrg 35105b261ecSmrg case XdbeBackground: 35205b261ecSmrg if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) 35305b261ecSmrg { 35405b261ecSmrg ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC); 35505b261ecSmrg clearRect.x = 0; 35605b261ecSmrg clearRect.y = 0; 35705b261ecSmrg clearRect.width = 35805b261ecSmrg pDbeWindowPrivPriv->pBackBuffer->drawable.width; 35905b261ecSmrg clearRect.height = 36005b261ecSmrg pDbeWindowPrivPriv->pBackBuffer->drawable.height; 36105b261ecSmrg (*pGC->ops->PolyFillRect)( 36205b261ecSmrg (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, 36305b261ecSmrg pGC, 1, &clearRect); 36405b261ecSmrg } 36505b261ecSmrg break; 36605b261ecSmrg 36705b261ecSmrg case XdbeUntouched: 36805b261ecSmrg /* Swap pixmap pointers. */ 36905b261ecSmrg pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer; 37005b261ecSmrg pDbeWindowPrivPriv->pBackBuffer = 37105b261ecSmrg pDbeWindowPrivPriv->pFrontBuffer; 37205b261ecSmrg pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer; 37305b261ecSmrg 37405b261ecSmrg miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv); 37505b261ecSmrg 37605b261ecSmrg break; 37705b261ecSmrg 37805b261ecSmrg case XdbeCopied: 37905b261ecSmrg break; 38005b261ecSmrg 38105b261ecSmrg } 38205b261ecSmrg 38305b261ecSmrg /* Remove the swapped window from the swap information array and decrement 38405b261ecSmrg * pNumWindows to indicate to the DIX level how many windows were actually 38505b261ecSmrg * swapped. 38605b261ecSmrg */ 38705b261ecSmrg 38805b261ecSmrg if (*pNumWindows > 1) 38905b261ecSmrg { 39005b261ecSmrg /* We were told to swap more than one window, but we only swapped the 39105b261ecSmrg * first one. Remove the first window in the list by moving the last 39205b261ecSmrg * window to the beginning. 39305b261ecSmrg */ 39405b261ecSmrg swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow; 39505b261ecSmrg swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction; 39605b261ecSmrg 39705b261ecSmrg /* Clear the last window information just to be safe. */ 39805b261ecSmrg swapInfo[*pNumWindows - 1].pWindow = (WindowPtr)NULL; 39905b261ecSmrg swapInfo[*pNumWindows - 1].swapAction = 0; 40005b261ecSmrg } 40105b261ecSmrg else 40205b261ecSmrg { 40305b261ecSmrg /* Clear the window information just to be safe. */ 40405b261ecSmrg swapInfo[0].pWindow = (WindowPtr)NULL; 40505b261ecSmrg swapInfo[0].swapAction = 0; 40605b261ecSmrg } 40705b261ecSmrg 40805b261ecSmrg (*pNumWindows)--; 40905b261ecSmrg 41005b261ecSmrg FreeScratchGC(pGC); 41105b261ecSmrg 41205b261ecSmrg return(Success); 41305b261ecSmrg 41405b261ecSmrg} /* miSwapBuffers() */ 41505b261ecSmrg 41605b261ecSmrg 41705b261ecSmrg/****************************************************************************** 41805b261ecSmrg * 41905b261ecSmrg * DBE MI Procedure: miDbeWinPrivDelete 42005b261ecSmrg * 42105b261ecSmrg * Description: 42205b261ecSmrg * 42305b261ecSmrg * This is the MI function for deleting the dbeWindowPrivResType resource. 42405b261ecSmrg * This function is invoked indirectly by calling FreeResource() to free 42505b261ecSmrg * the resources associated with a DBE buffer ID. There are 5 ways that 42605b261ecSmrg * miDbeWinPrivDelete() can be called by FreeResource(). They are: 42705b261ecSmrg * 42805b261ecSmrg * - A DBE window is destroyed, in which case the DbeDestroyWindow() 42905b261ecSmrg * wrapper is invoked. The wrapper calls FreeResource() for all DBE 43005b261ecSmrg * buffer IDs. 43105b261ecSmrg * 43205b261ecSmrg * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources 43305b261ecSmrg * after a buffer allocation failure. 43405b261ecSmrg * 43505b261ecSmrg * - The PositionWindow wrapper, miDbePositionWindow(), calls 43605b261ecSmrg * FreeResource() when it fails to create buffers of the new size. 43705b261ecSmrg * FreeResource() is called for all DBE buffer IDs. 43805b261ecSmrg * 43905b261ecSmrg * - FreeClientResources() calls FreeResource() when a client dies or the 44005b261ecSmrg * the server resets. 44105b261ecSmrg * 44205b261ecSmrg * When FreeResource() is called for a DBE buffer ID, the delete function 44305b261ecSmrg * for the only other type of DBE resource, dbeDrawableResType, is also 44405b261ecSmrg * invoked. This delete function (DbeDrawableDelete) is a NOOP to make 44505b261ecSmrg * resource deletion easier. It is not guaranteed which delete function is 44605b261ecSmrg * called first. Hence, we will let miDbeWinPrivDelete() free all DBE 44705b261ecSmrg * resources. 44805b261ecSmrg * 44905b261ecSmrg * This function deletes/frees the following stuff associated with 45005b261ecSmrg * the window private: 45105b261ecSmrg * 45205b261ecSmrg * - the ID node in the ID list representing the passed in ID. 45305b261ecSmrg * 45405b261ecSmrg * In addition, pDbeWindowPriv->nBufferIDs is decremented. 45505b261ecSmrg * 45605b261ecSmrg * If this function is called for the last/only buffer ID for a window, 45705b261ecSmrg * these are additionally deleted/freed: 45805b261ecSmrg * 45905b261ecSmrg * - the front and back pixmaps 46005b261ecSmrg * - the window priv itself 46105b261ecSmrg * 46205b261ecSmrg *****************************************************************************/ 46305b261ecSmrg 46405b261ecSmrgstatic void 46505b261ecSmrgmiDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId) 46605b261ecSmrg{ 46705b261ecSmrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 46805b261ecSmrg 46905b261ecSmrg 47005b261ecSmrg if (pDbeWindowPriv->nBufferIDs != 0) 47105b261ecSmrg { 47205b261ecSmrg /* We still have at least one more buffer ID associated with this 47305b261ecSmrg * window. 47405b261ecSmrg */ 47505b261ecSmrg return; 47605b261ecSmrg } 47705b261ecSmrg 47805b261ecSmrg 47905b261ecSmrg /* We have no more buffer IDs associated with this window. We need to 48005b261ecSmrg * free some stuff. 48105b261ecSmrg */ 48205b261ecSmrg 48305b261ecSmrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 48405b261ecSmrg 48505b261ecSmrg /* Destroy the front and back pixmaps. */ 48605b261ecSmrg if (pDbeWindowPrivPriv->pFrontBuffer) 48705b261ecSmrg { 48805b261ecSmrg (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)( 48905b261ecSmrg pDbeWindowPrivPriv->pFrontBuffer); 49005b261ecSmrg } 49105b261ecSmrg if (pDbeWindowPrivPriv->pBackBuffer) 49205b261ecSmrg { 49305b261ecSmrg (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)( 49405b261ecSmrg pDbeWindowPrivPriv->pBackBuffer); 49505b261ecSmrg } 49605b261ecSmrg 49705b261ecSmrg} /* miDbeWinPrivDelete() */ 49805b261ecSmrg 49905b261ecSmrg 50005b261ecSmrg/****************************************************************************** 50105b261ecSmrg * 50205b261ecSmrg * DBE MI Procedure: miDbePositionWindow 50305b261ecSmrg * 50405b261ecSmrg * Description: 50505b261ecSmrg * 50605b261ecSmrg * This function was cloned from miMbxPositionWindow() in mimultibuf.c. 50705b261ecSmrg * This function resizes the buffer when the window is resized. 50805b261ecSmrg * 50905b261ecSmrg *****************************************************************************/ 51005b261ecSmrg 51105b261ecSmrgstatic Bool 51205b261ecSmrgmiDbePositionWindow(WindowPtr pWin, int x, int y) 51305b261ecSmrg{ 51405b261ecSmrg ScreenPtr pScreen; 51505b261ecSmrg DbeScreenPrivPtr pDbeScreenPriv; 51605b261ecSmrg DbeWindowPrivPtr pDbeWindowPriv; 51705b261ecSmrg int width, height; 51805b261ecSmrg int dx, dy, dw, dh; 51905b261ecSmrg int sourcex, sourcey; 52005b261ecSmrg int destx, desty; 52105b261ecSmrg int savewidth, saveheight; 52205b261ecSmrg PixmapPtr pFrontBuffer; 52305b261ecSmrg PixmapPtr pBackBuffer; 52405b261ecSmrg Bool clear; 52505b261ecSmrg GCPtr pGC; 52605b261ecSmrg xRectangle clearRect; 52705b261ecSmrg Bool ret; 52805b261ecSmrg 52905b261ecSmrg 53005b261ecSmrg /* 53105b261ecSmrg ************************************************************************** 53205b261ecSmrg ** 1. Unwrap the member routine. 53305b261ecSmrg ************************************************************************** 53405b261ecSmrg */ 53505b261ecSmrg 53605b261ecSmrg pScreen = pWin->drawable.pScreen; 53705b261ecSmrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 53805b261ecSmrg pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; 53905b261ecSmrg 54005b261ecSmrg /* 54105b261ecSmrg ************************************************************************** 54205b261ecSmrg ** 2. Do any work necessary before the member routine is called. 54305b261ecSmrg ** 54405b261ecSmrg ** In this case we do not need to do anything. 54505b261ecSmrg ************************************************************************** 54605b261ecSmrg */ 54705b261ecSmrg 54805b261ecSmrg /* 54905b261ecSmrg ************************************************************************** 55005b261ecSmrg ** 3. Call the member routine, saving its result if necessary. 55105b261ecSmrg ************************************************************************** 55205b261ecSmrg */ 55305b261ecSmrg 55405b261ecSmrg ret = (*pScreen->PositionWindow)(pWin, x, y); 55505b261ecSmrg 55605b261ecSmrg /* 55705b261ecSmrg ************************************************************************** 55805b261ecSmrg ** 4. Rewrap the member routine, restoring the wrapper value first in case 55905b261ecSmrg ** the wrapper (or something that it wrapped) change this value. 56005b261ecSmrg ************************************************************************** 56105b261ecSmrg */ 56205b261ecSmrg 56305b261ecSmrg pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 56405b261ecSmrg pScreen->PositionWindow = miDbePositionWindow; 56505b261ecSmrg 56605b261ecSmrg /* 56705b261ecSmrg ************************************************************************** 56805b261ecSmrg ** 5. Do any work necessary after the member routine has been called. 56905b261ecSmrg ************************************************************************** 57005b261ecSmrg */ 57105b261ecSmrg 57205b261ecSmrg if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) 57305b261ecSmrg { 57405b261ecSmrg return(ret); 57505b261ecSmrg } 57605b261ecSmrg 57705b261ecSmrg if (pDbeWindowPriv->width == pWin->drawable.width && 57805b261ecSmrg pDbeWindowPriv->height == pWin->drawable.height) 57905b261ecSmrg { 58005b261ecSmrg return(ret); 58105b261ecSmrg } 58205b261ecSmrg 58305b261ecSmrg width = pWin->drawable.width; 58405b261ecSmrg height = pWin->drawable.height; 58505b261ecSmrg 58605b261ecSmrg dx = pWin->drawable.x - pDbeWindowPriv->x; 58705b261ecSmrg dy = pWin->drawable.y - pDbeWindowPriv->y; 58805b261ecSmrg dw = width - pDbeWindowPriv->width; 58905b261ecSmrg dh = height - pDbeWindowPriv->height; 59005b261ecSmrg 59105b261ecSmrg GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); 59205b261ecSmrg 59305b261ecSmrg clear = ((pDbeWindowPriv->width < (unsigned short)width ) || 59405b261ecSmrg (pDbeWindowPriv->height < (unsigned short)height) || 59505b261ecSmrg (pWin->bitGravity == ForgetGravity)); 59605b261ecSmrg 59705b261ecSmrg sourcex = 0; 59805b261ecSmrg sourcey = 0; 59905b261ecSmrg savewidth = pDbeWindowPriv->width; 60005b261ecSmrg saveheight = pDbeWindowPriv->height; 60105b261ecSmrg 60205b261ecSmrg /* Clip rectangle to source and destination. */ 60305b261ecSmrg if (destx < 0) 60405b261ecSmrg { 60505b261ecSmrg savewidth += destx; 60605b261ecSmrg sourcex -= destx; 60705b261ecSmrg destx = 0; 60805b261ecSmrg } 60905b261ecSmrg 61005b261ecSmrg if (destx + savewidth > width) 61105b261ecSmrg { 61205b261ecSmrg savewidth = width - destx; 61305b261ecSmrg } 61405b261ecSmrg 61505b261ecSmrg if (desty < 0) 61605b261ecSmrg { 61705b261ecSmrg saveheight += desty; 61805b261ecSmrg sourcey -= desty; 61905b261ecSmrg desty = 0; 62005b261ecSmrg } 62105b261ecSmrg 62205b261ecSmrg if (desty + saveheight > height) 62305b261ecSmrg { 62405b261ecSmrg saveheight = height - desty; 62505b261ecSmrg } 62605b261ecSmrg 62705b261ecSmrg pDbeWindowPriv->width = width; 62805b261ecSmrg pDbeWindowPriv->height = height; 62905b261ecSmrg pDbeWindowPriv->x = pWin->drawable.x; 63005b261ecSmrg pDbeWindowPriv->y = pWin->drawable.y; 63105b261ecSmrg 63205b261ecSmrg pGC = GetScratchGC (pWin->drawable.depth, pScreen); 63305b261ecSmrg 63405b261ecSmrg if (clear) 63505b261ecSmrg { 63605b261ecSmrg if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) 63705b261ecSmrg { 63805b261ecSmrg clearRect.x = 0; 63905b261ecSmrg clearRect.y = 0; 64005b261ecSmrg clearRect.width = width; 64105b261ecSmrg clearRect.height = height; 64205b261ecSmrg } 64305b261ecSmrg else 64405b261ecSmrg { 64505b261ecSmrg clear = FALSE; 64605b261ecSmrg } 64705b261ecSmrg } 64805b261ecSmrg 64905b261ecSmrg /* Create DBE buffer pixmaps equal to size of resized window. */ 65005b261ecSmrg pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, 65105b261ecSmrg pWin->drawable.depth); 65205b261ecSmrg 65305b261ecSmrg pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, 65405b261ecSmrg pWin->drawable.depth); 65505b261ecSmrg 65605b261ecSmrg if (!pFrontBuffer || !pBackBuffer) 65705b261ecSmrg { 65805b261ecSmrg /* We failed at creating 1 or 2 of the pixmaps. */ 65905b261ecSmrg 66005b261ecSmrg if (pFrontBuffer) 66105b261ecSmrg { 66205b261ecSmrg (*pScreen->DestroyPixmap)(pFrontBuffer); 66305b261ecSmrg } 66405b261ecSmrg 66505b261ecSmrg if (pBackBuffer) 66605b261ecSmrg { 66705b261ecSmrg (*pScreen->DestroyPixmap)(pBackBuffer); 66805b261ecSmrg } 66905b261ecSmrg 67005b261ecSmrg /* Destroy all buffers for this window. */ 67105b261ecSmrg while (pDbeWindowPriv) 67205b261ecSmrg { 67305b261ecSmrg /* DbeWindowPrivDelete() will free the window private if there no 67405b261ecSmrg * more buffer IDs associated with this window. 67505b261ecSmrg */ 67605b261ecSmrg FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); 67705b261ecSmrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 67805b261ecSmrg } 67905b261ecSmrg 68005b261ecSmrg FreeScratchGC(pGC); 68105b261ecSmrg return(FALSE); 68205b261ecSmrg } 68305b261ecSmrg 68405b261ecSmrg else 68505b261ecSmrg { 68605b261ecSmrg /* Clear out the new DBE buffer pixmaps. */ 68705b261ecSmrg 68805b261ecSmrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 68905b261ecSmrg 69005b261ecSmrg 69105b261ecSmrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 69205b261ecSmrg ValidateGC((DrawablePtr)pFrontBuffer, pGC); 69305b261ecSmrg 69405b261ecSmrg /* I suppose this could avoid quite a bit of work if 69505b261ecSmrg * it computed the minimal area required. 69605b261ecSmrg */ 69705b261ecSmrg if (clear) 69805b261ecSmrg { 69905b261ecSmrg (*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1, 70005b261ecSmrg &clearRect); 70105b261ecSmrg (*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1, 70205b261ecSmrg &clearRect); 70305b261ecSmrg } 70405b261ecSmrg 70505b261ecSmrg /* Copy the contents of the old DBE pixmaps to the new pixmaps. */ 70605b261ecSmrg if (pWin->bitGravity != ForgetGravity) 70705b261ecSmrg { 70805b261ecSmrg (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, 70905b261ecSmrg (DrawablePtr)pFrontBuffer, pGC, sourcex, 71005b261ecSmrg sourcey, savewidth, saveheight, destx, desty); 71105b261ecSmrg (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, 71205b261ecSmrg (DrawablePtr)pBackBuffer, pGC, sourcex, 71305b261ecSmrg sourcey, savewidth, saveheight, destx, desty); 71405b261ecSmrg } 71505b261ecSmrg 71605b261ecSmrg /* Destroy the old pixmaps, and point the DBE window priv to the new 71705b261ecSmrg * pixmaps. 71805b261ecSmrg */ 71905b261ecSmrg 72005b261ecSmrg (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); 72105b261ecSmrg (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer); 72205b261ecSmrg 72305b261ecSmrg pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer; 72405b261ecSmrg pDbeWindowPrivPriv->pBackBuffer = pBackBuffer; 72505b261ecSmrg 72605b261ecSmrg /* Make sure all XID are associated with the new back pixmap. */ 72705b261ecSmrg miDbeAliasBuffers(pDbeWindowPriv); 72805b261ecSmrg 72905b261ecSmrg FreeScratchGC(pGC); 73005b261ecSmrg } 73105b261ecSmrg 73205b261ecSmrg return(ret); 73305b261ecSmrg 73405b261ecSmrg} /* miDbePositionWindow() */ 73505b261ecSmrg 73605b261ecSmrg 73705b261ecSmrg/****************************************************************************** 73805b261ecSmrg * 73905b261ecSmrg * DBE MI Procedure: miDbeResetProc 74005b261ecSmrg * 74105b261ecSmrg * Description: 74205b261ecSmrg * 74305b261ecSmrg * This function is called from DbeResetProc(), which is called at the end 74405b261ecSmrg * of every server generation. This function peforms any MI-specific 74505b261ecSmrg * shutdown tasks. 74605b261ecSmrg * 74705b261ecSmrg *****************************************************************************/ 74805b261ecSmrg 74905b261ecSmrgstatic void 75005b261ecSmrgmiDbeResetProc(ScreenPtr pScreen) 75105b261ecSmrg{ 75205b261ecSmrg DbeScreenPrivPtr pDbeScreenPriv; 75305b261ecSmrg 75405b261ecSmrg 75505b261ecSmrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 75605b261ecSmrg 75705b261ecSmrg /* Unwrap wrappers */ 75805b261ecSmrg pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; 75905b261ecSmrg 76005b261ecSmrg} /* miDbeResetProc() */ 76105b261ecSmrg 76205b261ecSmrg 76305b261ecSmrg/****************************************************************************** 76405b261ecSmrg * 76505b261ecSmrg * DBE MI Procedure: miDbeInit 76605b261ecSmrg * 76705b261ecSmrg * Description: 76805b261ecSmrg * 76905b261ecSmrg * This is the MI initialization function called by DbeExtensionInit(). 77005b261ecSmrg * 77105b261ecSmrg *****************************************************************************/ 77205b261ecSmrg 77305b261ecSmrgBool 77405b261ecSmrgmiDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv) 77505b261ecSmrg{ 77605b261ecSmrg /* Copy resource types created by DIX */ 77705b261ecSmrg dbeDrawableResType = pDbeScreenPriv->dbeDrawableResType; 77805b261ecSmrg dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType; 77905b261ecSmrg 78005b261ecSmrg /* Copy private indices created by DIX */ 78105b261ecSmrg dbeScreenPrivIndex = pDbeScreenPriv->dbeScreenPrivIndex; 78205b261ecSmrg dbeWindowPrivIndex = pDbeScreenPriv->dbeWindowPrivIndex; 78305b261ecSmrg 78405b261ecSmrg /* Reset the window priv privs if generations do not match. */ 78505b261ecSmrg if (miDbePrivPrivGeneration != serverGeneration) 78605b261ecSmrg { 78705b261ecSmrg /* 78805b261ecSmrg ********************************************************************** 78905b261ecSmrg ** Allocate the window priv priv. 79005b261ecSmrg ********************************************************************** 79105b261ecSmrg */ 79205b261ecSmrg 79305b261ecSmrg miDbeWindowPrivPrivIndex = (*pDbeScreenPriv->AllocWinPrivPrivIndex)(); 79405b261ecSmrg 79505b261ecSmrg /* Make sure we only do this code once. */ 79605b261ecSmrg miDbePrivPrivGeneration = serverGeneration; 79705b261ecSmrg 79805b261ecSmrg } /* if -- Reset priv privs. */ 79905b261ecSmrg 80005b261ecSmrg if (!(*pDbeScreenPriv->AllocWinPrivPriv)(pScreen, 80105b261ecSmrg miDbeWindowPrivPrivIndex, sizeof(MiDbeWindowPrivPrivRec))) 80205b261ecSmrg { 80305b261ecSmrg return(FALSE); 80405b261ecSmrg } 80505b261ecSmrg 80605b261ecSmrg /* Wrap functions. */ 80705b261ecSmrg pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 80805b261ecSmrg pScreen->PositionWindow = miDbePositionWindow; 80905b261ecSmrg 81005b261ecSmrg /* Initialize the per-screen DBE function pointers. */ 81105b261ecSmrg pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo; 81205b261ecSmrg pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName; 81305b261ecSmrg pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers; 81405b261ecSmrg pDbeScreenPriv->BeginIdiom = 0; 81505b261ecSmrg pDbeScreenPriv->EndIdiom = 0; 81605b261ecSmrg pDbeScreenPriv->ResetProc = miDbeResetProc; 81705b261ecSmrg pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete; 81805b261ecSmrg 81905b261ecSmrg return(TRUE); 82005b261ecSmrg 82105b261ecSmrg} /* miDbeInit() */ 822