105b261ecSmrg/****************************************************************************** 235c4bbdfSmrg * 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: 1235c4bbdfSmrg * 1305b261ecSmrg * The above copyright notice and this permission notice shall be included 1405b261ecSmrg * in all copies or substantial portions of the Software. 1535c4bbdfSmrg * 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. 2335c4bbdfSmrg * 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. 2835c4bbdfSmrg * 2905b261ecSmrg * Machine-independent DBE code 3005b261ecSmrg * 3105b261ecSmrg *****************************************************************************/ 3205b261ecSmrg 3305b261ecSmrg/* INCLUDES */ 3405b261ecSmrg 3505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 3605b261ecSmrg#include <dix-config.h> 3705b261ecSmrg#endif 3805b261ecSmrg 3905b261ecSmrg#include <X11/X.h> 4005b261ecSmrg#include <X11/Xproto.h> 4105b261ecSmrg#include "misc.h" 4205b261ecSmrg#include "os.h" 4305b261ecSmrg#include "windowstr.h" 4405b261ecSmrg#include "scrnintstr.h" 4505b261ecSmrg#include "pixmapstr.h" 4605b261ecSmrg#include "extnsionst.h" 4705b261ecSmrg#include "dixstruct.h" 4805b261ecSmrg#include "resource.h" 4905b261ecSmrg#include "opaque.h" 5005b261ecSmrg#include "dbestruct.h" 5105b261ecSmrg#include "regionstr.h" 5205b261ecSmrg#include "gcstruct.h" 5305b261ecSmrg#include "inputstr.h" 5405b261ecSmrg#include "midbe.h" 554642e01fSmrg#include "xace.h" 5605b261ecSmrg 5705b261ecSmrg#include <stdio.h> 5805b261ecSmrg 5905b261ecSmrg 6005b261ecSmrg/****************************************************************************** 6105b261ecSmrg * 6205b261ecSmrg * DBE MI Procedure: miDbeGetVisualInfo 6305b261ecSmrg * 6405b261ecSmrg * Description: 6505b261ecSmrg * 6605b261ecSmrg * This is the MI function for the DbeGetVisualInfo request. This function 6705b261ecSmrg * is called through pDbeScreenPriv->GetVisualInfo. This function is also 6805b261ecSmrg * called for the DbeAllocateBackBufferName request at the extension level; 6905b261ecSmrg * it is called by ProcDbeAllocateBackBufferName() in dbe.c. 7005b261ecSmrg * 7105b261ecSmrg * If memory allocation fails or we can not get the visual info, this 7205b261ecSmrg * function returns FALSE. Otherwise, it returns TRUE for success. 7305b261ecSmrg * 7405b261ecSmrg *****************************************************************************/ 7505b261ecSmrg 7605b261ecSmrgstatic Bool 7735c4bbdfSmrgmiDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo) 7805b261ecSmrg{ 7935c4bbdfSmrg register int i, j, k; 8035c4bbdfSmrg register int count; 8135c4bbdfSmrg DepthPtr pDepth; 8235c4bbdfSmrg XdbeVisualInfo *visInfo; 8305b261ecSmrg 8405b261ecSmrg /* Determine number of visuals for this screen. */ 8535c4bbdfSmrg for (i = 0, count = 0; i < pScreen->numDepths; i++) { 8605b261ecSmrg count += pScreen->allowedDepths[i].numVids; 8705b261ecSmrg } 8805b261ecSmrg 8905b261ecSmrg /* Allocate an array of XdbeVisualInfo items. */ 9035c4bbdfSmrg if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) { 9135c4bbdfSmrg return FALSE; /* memory alloc failure */ 9205b261ecSmrg } 9305b261ecSmrg 9435c4bbdfSmrg for (i = 0, k = 0; i < pScreen->numDepths; i++) { 9505b261ecSmrg /* For each depth of this screen, get visual information. */ 9605b261ecSmrg 9705b261ecSmrg pDepth = &pScreen->allowedDepths[i]; 9805b261ecSmrg 9935c4bbdfSmrg for (j = 0; j < pDepth->numVids; j++) { 10005b261ecSmrg /* For each visual for this depth of this screen, get visual ID 10105b261ecSmrg * and visual depth. Since this is MI code, we will always return 10205b261ecSmrg * the same performance level for all visuals (0). A higher 10305b261ecSmrg * performance level value indicates higher performance. 10405b261ecSmrg */ 10535c4bbdfSmrg visInfo[k].visual = pDepth->vids[j]; 10635c4bbdfSmrg visInfo[k].depth = pDepth->depth; 10705b261ecSmrg visInfo[k].perflevel = 0; 10805b261ecSmrg k++; 10905b261ecSmrg } 11005b261ecSmrg } 11105b261ecSmrg 11205b261ecSmrg /* Record the number of visuals and point visual_depth to 11305b261ecSmrg * the array of visual info. 11405b261ecSmrg */ 11535c4bbdfSmrg pScrVisInfo->count = count; 11605b261ecSmrg pScrVisInfo->visinfo = visInfo; 11705b261ecSmrg 11835c4bbdfSmrg return TRUE; /* success */ 11905b261ecSmrg 12035c4bbdfSmrg} /* miDbeGetVisualInfo() */ 12105b261ecSmrg 12205b261ecSmrg/****************************************************************************** 12305b261ecSmrg * 12405b261ecSmrg * DBE MI Procedure: miAllocBackBufferName 12505b261ecSmrg * 12605b261ecSmrg * Description: 12705b261ecSmrg * 12805b261ecSmrg * This is the MI function for the DbeAllocateBackBufferName request. 12905b261ecSmrg * 13005b261ecSmrg *****************************************************************************/ 13105b261ecSmrg 13205b261ecSmrgstatic int 13305b261ecSmrgmiDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction) 13405b261ecSmrg{ 13535c4bbdfSmrg ScreenPtr pScreen; 13635c4bbdfSmrg DbeWindowPrivPtr pDbeWindowPriv; 13735c4bbdfSmrg DbeScreenPrivPtr pDbeScreenPriv; 13835c4bbdfSmrg GCPtr pGC; 13935c4bbdfSmrg xRectangle clearRect; 14035c4bbdfSmrg int rc; 14105b261ecSmrg 14205b261ecSmrg pScreen = pWin->drawable.pScreen; 14305b261ecSmrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 14405b261ecSmrg 14535c4bbdfSmrg if (pDbeWindowPriv->nBufferIDs == 0) { 14605b261ecSmrg /* There is no buffer associated with the window. 14705b261ecSmrg * We have to create the window priv priv. Remember, the window 14805b261ecSmrg * priv was created at the DIX level, so all we need to do is 14905b261ecSmrg * create the priv priv and attach it to the priv. 15005b261ecSmrg */ 15105b261ecSmrg 15205b261ecSmrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 15305b261ecSmrg 15405b261ecSmrg /* Get a front pixmap. */ 15535c4bbdfSmrg if (!(pDbeWindowPriv->pFrontBuffer = 15635c4bbdfSmrg (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, 15735c4bbdfSmrg pDbeWindowPriv->height, 15835c4bbdfSmrg pWin->drawable.depth, 0))) { 1596747b715Smrg return BadAlloc; 16005b261ecSmrg } 16105b261ecSmrg 16205b261ecSmrg /* Get a back pixmap. */ 16335c4bbdfSmrg if (!(pDbeWindowPriv->pBackBuffer = 16435c4bbdfSmrg (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, 16535c4bbdfSmrg pDbeWindowPriv->height, 16635c4bbdfSmrg pWin->drawable.depth, 0))) { 16735c4bbdfSmrg (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); 1686747b715Smrg return BadAlloc; 16905b261ecSmrg } 17005b261ecSmrg 17135c4bbdfSmrg /* Security creation/labeling check. */ 17235c4bbdfSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId, 17335c4bbdfSmrg dbeDrawableResType, pDbeWindowPriv->pBackBuffer, 17435c4bbdfSmrg RT_WINDOW, pWin, DixCreateAccess); 17505b261ecSmrg 17605b261ecSmrg /* Make the back pixmap a DBE drawable resource. */ 1774642e01fSmrg if (rc != Success || !AddResource(bufId, dbeDrawableResType, 17835c4bbdfSmrg pDbeWindowPriv->pBackBuffer)) { 17905b261ecSmrg /* free the buffer and the drawable resource */ 18005b261ecSmrg FreeResource(bufId, RT_NONE); 1814642e01fSmrg return (rc == Success) ? BadAlloc : rc; 18205b261ecSmrg } 18305b261ecSmrg 18405b261ecSmrg /* Clear the back buffer. */ 18505b261ecSmrg pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 18635c4bbdfSmrg if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { 18735c4bbdfSmrg ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); 18805b261ecSmrg clearRect.x = clearRect.y = 0; 18935c4bbdfSmrg clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; 19035c4bbdfSmrg clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; 19135c4bbdfSmrg (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> 19235c4bbdfSmrg pBackBuffer, pGC, 1, &clearRect); 19305b261ecSmrg } 19405b261ecSmrg FreeScratchGC(pGC); 19505b261ecSmrg 19635c4bbdfSmrg } /* if no buffer associated with the window */ 19705b261ecSmrg 19835c4bbdfSmrg else { 19905b261ecSmrg /* A buffer is already associated with the window. 20005b261ecSmrg * Place the new buffer ID information at the head of the ID list. 20105b261ecSmrg */ 20205b261ecSmrg 20305b261ecSmrg /* Associate the new ID with an existing pixmap. */ 20405b261ecSmrg if (!AddResource(bufId, dbeDrawableResType, 20535c4bbdfSmrg (void *) pDbeWindowPriv->pBackBuffer)) { 2066747b715Smrg return BadAlloc; 20705b261ecSmrg } 20805b261ecSmrg 20905b261ecSmrg } 21005b261ecSmrg 2116747b715Smrg return Success; 21205b261ecSmrg 21335c4bbdfSmrg} /* miDbeAllocBackBufferName() */ 21405b261ecSmrg 21505b261ecSmrg/****************************************************************************** 21605b261ecSmrg * 21705b261ecSmrg * DBE MI Procedure: miDbeAliasBuffers 21805b261ecSmrg * 21905b261ecSmrg * Description: 22005b261ecSmrg * 22105b261ecSmrg * This function associates all XIDs of a buffer with the back pixmap 22205b261ecSmrg * stored in the window priv. 22305b261ecSmrg * 22405b261ecSmrg *****************************************************************************/ 22505b261ecSmrg 22605b261ecSmrgstatic void 22705b261ecSmrgmiDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv) 22805b261ecSmrg{ 22935c4bbdfSmrg int i; 23005b261ecSmrg 23135c4bbdfSmrg for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) { 23205b261ecSmrg ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, 23335c4bbdfSmrg (void *) pDbeWindowPriv->pBackBuffer); 23405b261ecSmrg } 23505b261ecSmrg 23635c4bbdfSmrg} /* miDbeAliasBuffers() */ 23705b261ecSmrg 23805b261ecSmrg/****************************************************************************** 23905b261ecSmrg * 24005b261ecSmrg * DBE MI Procedure: miDbeSwapBuffers 24105b261ecSmrg * 24205b261ecSmrg * Description: 24305b261ecSmrg * 24405b261ecSmrg * This is the MI function for the DbeSwapBuffers request. 24505b261ecSmrg * 24605b261ecSmrg *****************************************************************************/ 24705b261ecSmrg 24805b261ecSmrgstatic int 24905b261ecSmrgmiDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo) 25005b261ecSmrg{ 25135c4bbdfSmrg DbeScreenPrivPtr pDbeScreenPriv; 25235c4bbdfSmrg DbeWindowPrivPtr pDbeWindowPriv; 25335c4bbdfSmrg GCPtr pGC; 25435c4bbdfSmrg WindowPtr pWin; 25535c4bbdfSmrg PixmapPtr pTmpBuffer; 25635c4bbdfSmrg xRectangle clearRect; 25735c4bbdfSmrg 25835c4bbdfSmrg pWin = swapInfo[0].pWindow; 25935c4bbdfSmrg pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); 26035c4bbdfSmrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 26105b261ecSmrg pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 26205b261ecSmrg 26305b261ecSmrg /* 26405b261ecSmrg ********************************************************************** 26505b261ecSmrg ** Setup before swap. 26605b261ecSmrg ********************************************************************** 26705b261ecSmrg */ 26805b261ecSmrg 26935c4bbdfSmrg switch (swapInfo[0].swapAction) { 27035c4bbdfSmrg case XdbeUndefined: 27135c4bbdfSmrg break; 27205b261ecSmrg 27335c4bbdfSmrg case XdbeBackground: 27435c4bbdfSmrg break; 27505b261ecSmrg 27635c4bbdfSmrg case XdbeUntouched: 27735c4bbdfSmrg ValidateGC((DrawablePtr) pDbeWindowPriv->pFrontBuffer, pGC); 27835c4bbdfSmrg (*pGC->ops->CopyArea) ((DrawablePtr) pWin, 27935c4bbdfSmrg (DrawablePtr) pDbeWindowPriv->pFrontBuffer, 28035c4bbdfSmrg pGC, 0, 0, pWin->drawable.width, 28135c4bbdfSmrg pWin->drawable.height, 0, 0); 28235c4bbdfSmrg break; 28305b261ecSmrg 28435c4bbdfSmrg case XdbeCopied: 28535c4bbdfSmrg break; 28605b261ecSmrg 28705b261ecSmrg } 28805b261ecSmrg 28905b261ecSmrg /* 29005b261ecSmrg ********************************************************************** 29105b261ecSmrg ** Swap. 29205b261ecSmrg ********************************************************************** 29305b261ecSmrg */ 29405b261ecSmrg 29535c4bbdfSmrg ValidateGC((DrawablePtr) pWin, pGC); 29635c4bbdfSmrg (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, 29735c4bbdfSmrg (DrawablePtr) pWin, pGC, 0, 0, 29835c4bbdfSmrg pWin->drawable.width, pWin->drawable.height, 0, 0); 29905b261ecSmrg 30005b261ecSmrg /* 30105b261ecSmrg ********************************************************************** 30205b261ecSmrg ** Tasks after swap. 30305b261ecSmrg ********************************************************************** 30405b261ecSmrg */ 30505b261ecSmrg 30635c4bbdfSmrg switch (swapInfo[0].swapAction) { 30735c4bbdfSmrg case XdbeUndefined: 30835c4bbdfSmrg break; 30935c4bbdfSmrg 31035c4bbdfSmrg case XdbeBackground: 31135c4bbdfSmrg if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { 31235c4bbdfSmrg ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); 31335c4bbdfSmrg clearRect.x = 0; 31435c4bbdfSmrg clearRect.y = 0; 31535c4bbdfSmrg clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; 31635c4bbdfSmrg clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; 31735c4bbdfSmrg (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> 31835c4bbdfSmrg pBackBuffer, pGC, 1, &clearRect); 31935c4bbdfSmrg } 32035c4bbdfSmrg break; 32135c4bbdfSmrg 32235c4bbdfSmrg case XdbeUntouched: 32335c4bbdfSmrg /* Swap pixmap pointers. */ 32435c4bbdfSmrg pTmpBuffer = pDbeWindowPriv->pBackBuffer; 32535c4bbdfSmrg pDbeWindowPriv->pBackBuffer = pDbeWindowPriv->pFrontBuffer; 32635c4bbdfSmrg pDbeWindowPriv->pFrontBuffer = pTmpBuffer; 32735c4bbdfSmrg 32835c4bbdfSmrg miDbeAliasBuffers(pDbeWindowPriv); 32935c4bbdfSmrg 33035c4bbdfSmrg break; 33135c4bbdfSmrg 33235c4bbdfSmrg case XdbeCopied: 33335c4bbdfSmrg break; 33405b261ecSmrg 33505b261ecSmrg } 33605b261ecSmrg 33705b261ecSmrg /* Remove the swapped window from the swap information array and decrement 33805b261ecSmrg * pNumWindows to indicate to the DIX level how many windows were actually 33905b261ecSmrg * swapped. 34005b261ecSmrg */ 34105b261ecSmrg 34235c4bbdfSmrg if (*pNumWindows > 1) { 34305b261ecSmrg /* We were told to swap more than one window, but we only swapped the 34405b261ecSmrg * first one. Remove the first window in the list by moving the last 34505b261ecSmrg * window to the beginning. 34605b261ecSmrg */ 34735c4bbdfSmrg swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow; 34805b261ecSmrg swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction; 34905b261ecSmrg 35005b261ecSmrg /* Clear the last window information just to be safe. */ 35135c4bbdfSmrg swapInfo[*pNumWindows - 1].pWindow = (WindowPtr) NULL; 35205b261ecSmrg swapInfo[*pNumWindows - 1].swapAction = 0; 35305b261ecSmrg } 35435c4bbdfSmrg else { 35505b261ecSmrg /* Clear the window information just to be safe. */ 35635c4bbdfSmrg swapInfo[0].pWindow = (WindowPtr) NULL; 35705b261ecSmrg swapInfo[0].swapAction = 0; 35805b261ecSmrg } 35905b261ecSmrg 36005b261ecSmrg (*pNumWindows)--; 36105b261ecSmrg 36205b261ecSmrg FreeScratchGC(pGC); 36305b261ecSmrg 3646747b715Smrg return Success; 36505b261ecSmrg 36635c4bbdfSmrg} /* miSwapBuffers() */ 36705b261ecSmrg 36805b261ecSmrg/****************************************************************************** 36905b261ecSmrg * 37005b261ecSmrg * DBE MI Procedure: miDbeWinPrivDelete 37105b261ecSmrg * 37205b261ecSmrg * Description: 37305b261ecSmrg * 37405b261ecSmrg * This is the MI function for deleting the dbeWindowPrivResType resource. 37505b261ecSmrg * This function is invoked indirectly by calling FreeResource() to free 37605b261ecSmrg * the resources associated with a DBE buffer ID. There are 5 ways that 37705b261ecSmrg * miDbeWinPrivDelete() can be called by FreeResource(). They are: 37805b261ecSmrg * 37905b261ecSmrg * - A DBE window is destroyed, in which case the DbeDestroyWindow() 38005b261ecSmrg * wrapper is invoked. The wrapper calls FreeResource() for all DBE 38105b261ecSmrg * buffer IDs. 38205b261ecSmrg * 38305b261ecSmrg * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources 38405b261ecSmrg * after a buffer allocation failure. 38505b261ecSmrg * 38605b261ecSmrg * - The PositionWindow wrapper, miDbePositionWindow(), calls 38705b261ecSmrg * FreeResource() when it fails to create buffers of the new size. 38805b261ecSmrg * FreeResource() is called for all DBE buffer IDs. 38905b261ecSmrg * 39005b261ecSmrg * - FreeClientResources() calls FreeResource() when a client dies or the 39105b261ecSmrg * the server resets. 39205b261ecSmrg * 39305b261ecSmrg * When FreeResource() is called for a DBE buffer ID, the delete function 39405b261ecSmrg * for the only other type of DBE resource, dbeDrawableResType, is also 39505b261ecSmrg * invoked. This delete function (DbeDrawableDelete) is a NOOP to make 39605b261ecSmrg * resource deletion easier. It is not guaranteed which delete function is 39705b261ecSmrg * called first. Hence, we will let miDbeWinPrivDelete() free all DBE 39805b261ecSmrg * resources. 39935c4bbdfSmrg * 40005b261ecSmrg * This function deletes/frees the following stuff associated with 40105b261ecSmrg * the window private: 40205b261ecSmrg * 40305b261ecSmrg * - the ID node in the ID list representing the passed in ID. 40405b261ecSmrg * 40505b261ecSmrg * In addition, pDbeWindowPriv->nBufferIDs is decremented. 40605b261ecSmrg * 40705b261ecSmrg * If this function is called for the last/only buffer ID for a window, 40805b261ecSmrg * these are additionally deleted/freed: 40905b261ecSmrg * 41005b261ecSmrg * - the front and back pixmaps 41105b261ecSmrg * - the window priv itself 41205b261ecSmrg * 41305b261ecSmrg *****************************************************************************/ 41405b261ecSmrg 41505b261ecSmrgstatic void 41605b261ecSmrgmiDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId) 41705b261ecSmrg{ 41835c4bbdfSmrg if (pDbeWindowPriv->nBufferIDs != 0) { 41905b261ecSmrg /* We still have at least one more buffer ID associated with this 42005b261ecSmrg * window. 42105b261ecSmrg */ 42205b261ecSmrg return; 42305b261ecSmrg } 42405b261ecSmrg 42505b261ecSmrg /* We have no more buffer IDs associated with this window. We need to 42605b261ecSmrg * free some stuff. 42705b261ecSmrg */ 42805b261ecSmrg 42905b261ecSmrg /* Destroy the front and back pixmaps. */ 43035c4bbdfSmrg if (pDbeWindowPriv->pFrontBuffer) { 43135c4bbdfSmrg (*pDbeWindowPriv->pWindow->drawable.pScreen-> 43235c4bbdfSmrg DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); 43305b261ecSmrg } 43435c4bbdfSmrg if (pDbeWindowPriv->pBackBuffer) { 43535c4bbdfSmrg (*pDbeWindowPriv->pWindow->drawable.pScreen-> 43635c4bbdfSmrg DestroyPixmap) (pDbeWindowPriv->pBackBuffer); 43705b261ecSmrg } 43835c4bbdfSmrg} /* miDbeWinPrivDelete() */ 43905b261ecSmrg 44005b261ecSmrg/****************************************************************************** 44105b261ecSmrg * 44205b261ecSmrg * DBE MI Procedure: miDbePositionWindow 44305b261ecSmrg * 44405b261ecSmrg * Description: 44505b261ecSmrg * 44635c4bbdfSmrg * This function was cloned from miMbxPositionWindow() in mimultibuf.c. 44705b261ecSmrg * This function resizes the buffer when the window is resized. 44805b261ecSmrg * 44905b261ecSmrg *****************************************************************************/ 45005b261ecSmrg 45105b261ecSmrgstatic Bool 45205b261ecSmrgmiDbePositionWindow(WindowPtr pWin, int x, int y) 45305b261ecSmrg{ 45435c4bbdfSmrg ScreenPtr pScreen; 45535c4bbdfSmrg DbeScreenPrivPtr pDbeScreenPriv; 45635c4bbdfSmrg DbeWindowPrivPtr pDbeWindowPriv; 45735c4bbdfSmrg int width, height; 45835c4bbdfSmrg int dx, dy, dw, dh; 45935c4bbdfSmrg int sourcex, sourcey; 46035c4bbdfSmrg int destx, desty; 46135c4bbdfSmrg int savewidth, saveheight; 46235c4bbdfSmrg PixmapPtr pFrontBuffer; 46335c4bbdfSmrg PixmapPtr pBackBuffer; 46435c4bbdfSmrg Bool clear; 46535c4bbdfSmrg GCPtr pGC; 46635c4bbdfSmrg xRectangle clearRect; 46735c4bbdfSmrg Bool ret; 46805b261ecSmrg 46905b261ecSmrg /* 47005b261ecSmrg ************************************************************************** 47105b261ecSmrg ** 1. Unwrap the member routine. 47205b261ecSmrg ************************************************************************** 47305b261ecSmrg */ 47435c4bbdfSmrg 47535c4bbdfSmrg pScreen = pWin->drawable.pScreen; 47635c4bbdfSmrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 47705b261ecSmrg pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; 47805b261ecSmrg 47905b261ecSmrg /* 48005b261ecSmrg ************************************************************************** 48105b261ecSmrg ** 2. Do any work necessary before the member routine is called. 48205b261ecSmrg ** 48305b261ecSmrg ** In this case we do not need to do anything. 48405b261ecSmrg ************************************************************************** 48505b261ecSmrg */ 48635c4bbdfSmrg 48705b261ecSmrg /* 48805b261ecSmrg ************************************************************************** 48905b261ecSmrg ** 3. Call the member routine, saving its result if necessary. 49005b261ecSmrg ************************************************************************** 49105b261ecSmrg */ 49235c4bbdfSmrg 49335c4bbdfSmrg ret = (*pScreen->PositionWindow) (pWin, x, y); 49405b261ecSmrg 49505b261ecSmrg /* 49605b261ecSmrg ************************************************************************** 49705b261ecSmrg ** 4. Rewrap the member routine, restoring the wrapper value first in case 49805b261ecSmrg ** the wrapper (or something that it wrapped) change this value. 49905b261ecSmrg ************************************************************************** 50005b261ecSmrg */ 50105b261ecSmrg 50205b261ecSmrg pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 50305b261ecSmrg pScreen->PositionWindow = miDbePositionWindow; 50405b261ecSmrg 50505b261ecSmrg /* 50605b261ecSmrg ************************************************************************** 50705b261ecSmrg ** 5. Do any work necessary after the member routine has been called. 50805b261ecSmrg ************************************************************************** 50905b261ecSmrg */ 51035c4bbdfSmrg 51135c4bbdfSmrg if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) { 51235c4bbdfSmrg return ret; 51305b261ecSmrg } 51405b261ecSmrg 51535c4bbdfSmrg if (pDbeWindowPriv->width == pWin->drawable.width && 51635c4bbdfSmrg pDbeWindowPriv->height == pWin->drawable.height) { 51735c4bbdfSmrg return ret; 51805b261ecSmrg } 51905b261ecSmrg 52035c4bbdfSmrg width = pWin->drawable.width; 52105b261ecSmrg height = pWin->drawable.height; 52205b261ecSmrg 52305b261ecSmrg dx = pWin->drawable.x - pDbeWindowPriv->x; 52405b261ecSmrg dy = pWin->drawable.y - pDbeWindowPriv->y; 52535c4bbdfSmrg dw = width - pDbeWindowPriv->width; 52605b261ecSmrg dh = height - pDbeWindowPriv->height; 52705b261ecSmrg 52835c4bbdfSmrg GravityTranslate(0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); 52905b261ecSmrg 53035c4bbdfSmrg clear = ((pDbeWindowPriv->width < (unsigned short) width) || 53135c4bbdfSmrg (pDbeWindowPriv->height < (unsigned short) height) || 53205b261ecSmrg (pWin->bitGravity == ForgetGravity)); 53305b261ecSmrg 53405b261ecSmrg sourcex = 0; 53505b261ecSmrg sourcey = 0; 53635c4bbdfSmrg savewidth = pDbeWindowPriv->width; 53705b261ecSmrg saveheight = pDbeWindowPriv->height; 53805b261ecSmrg 53905b261ecSmrg /* Clip rectangle to source and destination. */ 54035c4bbdfSmrg if (destx < 0) { 54135c4bbdfSmrg savewidth += destx; 54235c4bbdfSmrg sourcex -= destx; 54335c4bbdfSmrg destx = 0; 54405b261ecSmrg } 54505b261ecSmrg 54635c4bbdfSmrg if (destx + savewidth > width) { 54735c4bbdfSmrg savewidth = width - destx; 54805b261ecSmrg } 54905b261ecSmrg 55035c4bbdfSmrg if (desty < 0) { 55135c4bbdfSmrg saveheight += desty; 55235c4bbdfSmrg sourcey -= desty; 55335c4bbdfSmrg desty = 0; 55405b261ecSmrg } 55505b261ecSmrg 55635c4bbdfSmrg if (desty + saveheight > height) { 55735c4bbdfSmrg saveheight = height - desty; 55805b261ecSmrg } 55905b261ecSmrg 56035c4bbdfSmrg pDbeWindowPriv->width = width; 56105b261ecSmrg pDbeWindowPriv->height = height; 56205b261ecSmrg pDbeWindowPriv->x = pWin->drawable.x; 56305b261ecSmrg pDbeWindowPriv->y = pWin->drawable.y; 56405b261ecSmrg 56535c4bbdfSmrg pGC = GetScratchGC(pWin->drawable.depth, pScreen); 56635c4bbdfSmrg 56735c4bbdfSmrg if (clear) { 56835c4bbdfSmrg if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { 56935c4bbdfSmrg clearRect.x = 0; 57035c4bbdfSmrg clearRect.y = 0; 57135c4bbdfSmrg clearRect.width = width; 57235c4bbdfSmrg clearRect.height = height; 57335c4bbdfSmrg } 57435c4bbdfSmrg else { 57535c4bbdfSmrg clear = FALSE; 57635c4bbdfSmrg } 57705b261ecSmrg } 57805b261ecSmrg 57905b261ecSmrg /* Create DBE buffer pixmaps equal to size of resized window. */ 58035c4bbdfSmrg pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, 58135c4bbdfSmrg pWin->drawable.depth, 0); 58205b261ecSmrg 58335c4bbdfSmrg pBackBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, 58435c4bbdfSmrg pWin->drawable.depth, 0); 58505b261ecSmrg 58635c4bbdfSmrg if (!pFrontBuffer || !pBackBuffer) { 58705b261ecSmrg /* We failed at creating 1 or 2 of the pixmaps. */ 58805b261ecSmrg 58935c4bbdfSmrg if (pFrontBuffer) { 59035c4bbdfSmrg (*pScreen->DestroyPixmap) (pFrontBuffer); 59105b261ecSmrg } 59205b261ecSmrg 59335c4bbdfSmrg if (pBackBuffer) { 59435c4bbdfSmrg (*pScreen->DestroyPixmap) (pBackBuffer); 59505b261ecSmrg } 59605b261ecSmrg 59705b261ecSmrg /* Destroy all buffers for this window. */ 59835c4bbdfSmrg while (pDbeWindowPriv) { 59905b261ecSmrg /* DbeWindowPrivDelete() will free the window private if there no 60005b261ecSmrg * more buffer IDs associated with this window. 60105b261ecSmrg */ 60205b261ecSmrg FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); 60305b261ecSmrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 60405b261ecSmrg } 60505b261ecSmrg 60605b261ecSmrg FreeScratchGC(pGC); 6076747b715Smrg return FALSE; 60805b261ecSmrg } 60905b261ecSmrg 61035c4bbdfSmrg else { 61105b261ecSmrg /* Clear out the new DBE buffer pixmaps. */ 61205b261ecSmrg 61335c4bbdfSmrg /* I suppose this could avoid quite a bit of work if 61435c4bbdfSmrg * it computed the minimal area required. 61535c4bbdfSmrg */ 61635c4bbdfSmrg ValidateGC(&pFrontBuffer->drawable, pGC); 61735c4bbdfSmrg if (clear) { 61835c4bbdfSmrg (*pGC->ops->PolyFillRect) ((DrawablePtr) pFrontBuffer, pGC, 1, 61935c4bbdfSmrg &clearRect); 62035c4bbdfSmrg } 62135c4bbdfSmrg /* Copy the contents of the old front pixmap to the new one. */ 62235c4bbdfSmrg if (pWin->bitGravity != ForgetGravity) { 62335c4bbdfSmrg (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pFrontBuffer, 62435c4bbdfSmrg (DrawablePtr) pFrontBuffer, pGC, 62535c4bbdfSmrg sourcex, sourcey, savewidth, saveheight, 62635c4bbdfSmrg destx, desty); 6276747b715Smrg } 6286747b715Smrg 62935c4bbdfSmrg ValidateGC(&pBackBuffer->drawable, pGC); 63035c4bbdfSmrg if (clear) { 63135c4bbdfSmrg (*pGC->ops->PolyFillRect) ((DrawablePtr) pBackBuffer, pGC, 1, 63235c4bbdfSmrg &clearRect); 63335c4bbdfSmrg } 63435c4bbdfSmrg /* Copy the contents of the old back pixmap to the new one. */ 63535c4bbdfSmrg if (pWin->bitGravity != ForgetGravity) { 63635c4bbdfSmrg (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, 63735c4bbdfSmrg (DrawablePtr) pBackBuffer, pGC, 63835c4bbdfSmrg sourcex, sourcey, savewidth, saveheight, 63935c4bbdfSmrg destx, desty); 64035c4bbdfSmrg } 64105b261ecSmrg 64205b261ecSmrg /* Destroy the old pixmaps, and point the DBE window priv to the new 64305b261ecSmrg * pixmaps. 64405b261ecSmrg */ 64505b261ecSmrg 64635c4bbdfSmrg (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); 64735c4bbdfSmrg (*pScreen->DestroyPixmap) (pDbeWindowPriv->pBackBuffer); 64805b261ecSmrg 64935c4bbdfSmrg pDbeWindowPriv->pFrontBuffer = pFrontBuffer; 65035c4bbdfSmrg pDbeWindowPriv->pBackBuffer = pBackBuffer; 65105b261ecSmrg 65235c4bbdfSmrg /* Make sure all XID are associated with the new back pixmap. */ 65305b261ecSmrg miDbeAliasBuffers(pDbeWindowPriv); 65405b261ecSmrg 65505b261ecSmrg FreeScratchGC(pGC); 65605b261ecSmrg } 65705b261ecSmrg 6586747b715Smrg return ret; 65905b261ecSmrg 66035c4bbdfSmrg} /* miDbePositionWindow() */ 66105b261ecSmrg 66205b261ecSmrg/****************************************************************************** 66305b261ecSmrg * 66405b261ecSmrg * DBE MI Procedure: miDbeInit 66505b261ecSmrg * 66605b261ecSmrg * Description: 66705b261ecSmrg * 66805b261ecSmrg * This is the MI initialization function called by DbeExtensionInit(). 66905b261ecSmrg * 67005b261ecSmrg *****************************************************************************/ 67105b261ecSmrg 67205b261ecSmrgBool 67305b261ecSmrgmiDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv) 67405b261ecSmrg{ 67505b261ecSmrg /* Wrap functions. */ 67605b261ecSmrg pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 67735c4bbdfSmrg pScreen->PositionWindow = miDbePositionWindow; 67805b261ecSmrg 67905b261ecSmrg /* Initialize the per-screen DBE function pointers. */ 68035c4bbdfSmrg pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo; 68135c4bbdfSmrg pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName; 68235c4bbdfSmrg pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers; 68335c4bbdfSmrg pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete; 68405b261ecSmrg 6856747b715Smrg return TRUE; 68605b261ecSmrg 68735c4bbdfSmrg} /* miDbeInit() */ 688