1706f2543Smrg/****************************************************************************** 2706f2543Smrg * 3706f2543Smrg * Copyright (c) 1994, 1995 Hewlett-Packard Company 4706f2543Smrg * 5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 6706f2543Smrg * a copy of this software and associated documentation files (the 7706f2543Smrg * "Software"), to deal in the Software without restriction, including 8706f2543Smrg * without limitation the rights to use, copy, modify, merge, publish, 9706f2543Smrg * distribute, sublicense, and/or sell copies of the Software, and to 10706f2543Smrg * permit persons to whom the Software is furnished to do so, subject to 11706f2543Smrg * the following conditions: 12706f2543Smrg * 13706f2543Smrg * The above copyright notice and this permission notice shall be included 14706f2543Smrg * in all copies or substantial portions of the Software. 15706f2543Smrg * 16706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17706f2543Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19706f2543Smrg * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, 20706f2543Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21706f2543Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 22706f2543Smrg * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23706f2543Smrg * 24706f2543Smrg * Except as contained in this notice, the name of the Hewlett-Packard 25706f2543Smrg * Company shall not be used in advertising or otherwise to promote the 26706f2543Smrg * sale, use or other dealings in this Software without prior written 27706f2543Smrg * authorization from the Hewlett-Packard Company. 28706f2543Smrg * 29706f2543Smrg * Machine-independent DBE code 30706f2543Smrg * 31706f2543Smrg *****************************************************************************/ 32706f2543Smrg 33706f2543Smrg 34706f2543Smrg/* INCLUDES */ 35706f2543Smrg 36706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 37706f2543Smrg#include <dix-config.h> 38706f2543Smrg#endif 39706f2543Smrg 40706f2543Smrg#include <X11/X.h> 41706f2543Smrg#include <X11/Xproto.h> 42706f2543Smrg#include "misc.h" 43706f2543Smrg#include "os.h" 44706f2543Smrg#include "windowstr.h" 45706f2543Smrg#include "scrnintstr.h" 46706f2543Smrg#include "pixmapstr.h" 47706f2543Smrg#include "extnsionst.h" 48706f2543Smrg#include "dixstruct.h" 49706f2543Smrg#include "resource.h" 50706f2543Smrg#include "opaque.h" 51706f2543Smrg#include "dbestruct.h" 52706f2543Smrg#include "midbestr.h" 53706f2543Smrg#include "regionstr.h" 54706f2543Smrg#include "gcstruct.h" 55706f2543Smrg#include "inputstr.h" 56706f2543Smrg#include "midbe.h" 57706f2543Smrg#include "xace.h" 58706f2543Smrg 59706f2543Smrg#include <stdio.h> 60706f2543Smrg 61706f2543Smrgstatic DevPrivateKeyRec miDbeWindowPrivPrivKeyRec; 62706f2543Smrg#define miDbeWindowPrivPrivKey (&miDbeWindowPrivPrivKeyRec) 63706f2543Smrg 64706f2543Smrg 65706f2543Smrg/****************************************************************************** 66706f2543Smrg * 67706f2543Smrg * DBE MI Procedure: miDbeGetVisualInfo 68706f2543Smrg * 69706f2543Smrg * Description: 70706f2543Smrg * 71706f2543Smrg * This is the MI function for the DbeGetVisualInfo request. This function 72706f2543Smrg * is called through pDbeScreenPriv->GetVisualInfo. This function is also 73706f2543Smrg * called for the DbeAllocateBackBufferName request at the extension level; 74706f2543Smrg * it is called by ProcDbeAllocateBackBufferName() in dbe.c. 75706f2543Smrg * 76706f2543Smrg * If memory allocation fails or we can not get the visual info, this 77706f2543Smrg * function returns FALSE. Otherwise, it returns TRUE for success. 78706f2543Smrg * 79706f2543Smrg *****************************************************************************/ 80706f2543Smrg 81706f2543Smrgstatic Bool 82706f2543SmrgmiDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo *pScrVisInfo) 83706f2543Smrg{ 84706f2543Smrg register int i, j, k; 85706f2543Smrg register int count; 86706f2543Smrg DepthPtr pDepth; 87706f2543Smrg XdbeVisualInfo *visInfo; 88706f2543Smrg 89706f2543Smrg 90706f2543Smrg /* Determine number of visuals for this screen. */ 91706f2543Smrg for (i = 0, count = 0; i < pScreen->numDepths; i++) 92706f2543Smrg { 93706f2543Smrg count += pScreen->allowedDepths[i].numVids; 94706f2543Smrg } 95706f2543Smrg 96706f2543Smrg /* Allocate an array of XdbeVisualInfo items. */ 97706f2543Smrg if (!(visInfo = (XdbeVisualInfo *)malloc(count * sizeof(XdbeVisualInfo)))) 98706f2543Smrg { 99706f2543Smrg return FALSE; /* memory alloc failure */ 100706f2543Smrg } 101706f2543Smrg 102706f2543Smrg for (i = 0, k = 0; i < pScreen->numDepths; i++) 103706f2543Smrg { 104706f2543Smrg /* For each depth of this screen, get visual information. */ 105706f2543Smrg 106706f2543Smrg pDepth = &pScreen->allowedDepths[i]; 107706f2543Smrg 108706f2543Smrg for (j = 0; j < pDepth->numVids; j++) 109706f2543Smrg { 110706f2543Smrg /* For each visual for this depth of this screen, get visual ID 111706f2543Smrg * and visual depth. Since this is MI code, we will always return 112706f2543Smrg * the same performance level for all visuals (0). A higher 113706f2543Smrg * performance level value indicates higher performance. 114706f2543Smrg */ 115706f2543Smrg visInfo[k].visual = pDepth->vids[j]; 116706f2543Smrg visInfo[k].depth = pDepth->depth; 117706f2543Smrg visInfo[k].perflevel = 0; 118706f2543Smrg k++; 119706f2543Smrg } 120706f2543Smrg } 121706f2543Smrg 122706f2543Smrg /* Record the number of visuals and point visual_depth to 123706f2543Smrg * the array of visual info. 124706f2543Smrg */ 125706f2543Smrg pScrVisInfo->count = count; 126706f2543Smrg pScrVisInfo->visinfo = visInfo; 127706f2543Smrg 128706f2543Smrg return TRUE; /* success */ 129706f2543Smrg 130706f2543Smrg} /* miDbeGetVisualInfo() */ 131706f2543Smrg 132706f2543Smrg 133706f2543Smrg/****************************************************************************** 134706f2543Smrg * 135706f2543Smrg * DBE MI Procedure: miAllocBackBufferName 136706f2543Smrg * 137706f2543Smrg * Description: 138706f2543Smrg * 139706f2543Smrg * This is the MI function for the DbeAllocateBackBufferName request. 140706f2543Smrg * 141706f2543Smrg *****************************************************************************/ 142706f2543Smrg 143706f2543Smrgstatic int 144706f2543SmrgmiDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction) 145706f2543Smrg{ 146706f2543Smrg ScreenPtr pScreen; 147706f2543Smrg DbeWindowPrivPtr pDbeWindowPriv; 148706f2543Smrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 149706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 150706f2543Smrg GCPtr pGC; 151706f2543Smrg xRectangle clearRect; 152706f2543Smrg int rc; 153706f2543Smrg 154706f2543Smrg 155706f2543Smrg pScreen = pWin->drawable.pScreen; 156706f2543Smrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 157706f2543Smrg 158706f2543Smrg if (pDbeWindowPriv->nBufferIDs == 0) 159706f2543Smrg { 160706f2543Smrg /* There is no buffer associated with the window. 161706f2543Smrg * We have to create the window priv priv. Remember, the window 162706f2543Smrg * priv was created at the DIX level, so all we need to do is 163706f2543Smrg * create the priv priv and attach it to the priv. 164706f2543Smrg */ 165706f2543Smrg 166706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 167706f2543Smrg 168706f2543Smrg /* Setup the window priv priv. */ 169706f2543Smrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 170706f2543Smrg pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv; 171706f2543Smrg 172706f2543Smrg /* Get a front pixmap. */ 173706f2543Smrg if (!(pDbeWindowPrivPriv->pFrontBuffer = 174706f2543Smrg (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, 175706f2543Smrg pDbeWindowPriv->height, 176706f2543Smrg pWin->drawable.depth, 0))) 177706f2543Smrg { 178706f2543Smrg return BadAlloc; 179706f2543Smrg } 180706f2543Smrg 181706f2543Smrg /* Get a back pixmap. */ 182706f2543Smrg if (!(pDbeWindowPrivPriv->pBackBuffer = 183706f2543Smrg (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, 184706f2543Smrg pDbeWindowPriv->height, 185706f2543Smrg pWin->drawable.depth, 0))) 186706f2543Smrg { 187706f2543Smrg (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); 188706f2543Smrg return BadAlloc; 189706f2543Smrg } 190706f2543Smrg 191706f2543Smrg /* Security creation/labeling check. */ 192706f2543Smrg rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId, 193706f2543Smrg dbeDrawableResType, pDbeWindowPrivPriv->pBackBuffer, 194706f2543Smrg RT_WINDOW, pWin, DixCreateAccess); 195706f2543Smrg 196706f2543Smrg /* Make the back pixmap a DBE drawable resource. */ 197706f2543Smrg if (rc != Success || !AddResource(bufId, dbeDrawableResType, 198706f2543Smrg pDbeWindowPrivPriv->pBackBuffer)) 199706f2543Smrg { 200706f2543Smrg /* free the buffer and the drawable resource */ 201706f2543Smrg FreeResource(bufId, RT_NONE); 202706f2543Smrg return (rc == Success) ? BadAlloc : rc; 203706f2543Smrg } 204706f2543Smrg 205706f2543Smrg /* Clear the back buffer. */ 206706f2543Smrg pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 207706f2543Smrg if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) 208706f2543Smrg { 209706f2543Smrg ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC); 210706f2543Smrg clearRect.x = clearRect.y = 0; 211706f2543Smrg clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width; 212706f2543Smrg clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height; 213706f2543Smrg (*pGC->ops->PolyFillRect)( 214706f2543Smrg (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1, 215706f2543Smrg &clearRect); 216706f2543Smrg } 217706f2543Smrg FreeScratchGC(pGC); 218706f2543Smrg 219706f2543Smrg } /* if no buffer associated with the window */ 220706f2543Smrg 221706f2543Smrg else 222706f2543Smrg { 223706f2543Smrg /* A buffer is already associated with the window. 224706f2543Smrg * Place the new buffer ID information at the head of the ID list. 225706f2543Smrg */ 226706f2543Smrg 227706f2543Smrg /* Associate the new ID with an existing pixmap. */ 228706f2543Smrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 229706f2543Smrg if (!AddResource(bufId, dbeDrawableResType, 230706f2543Smrg (pointer)pDbeWindowPrivPriv->pBackBuffer)) 231706f2543Smrg { 232706f2543Smrg return BadAlloc; 233706f2543Smrg } 234706f2543Smrg 235706f2543Smrg } 236706f2543Smrg 237706f2543Smrg return Success; 238706f2543Smrg 239706f2543Smrg} /* miDbeAllocBackBufferName() */ 240706f2543Smrg 241706f2543Smrg 242706f2543Smrg/****************************************************************************** 243706f2543Smrg * 244706f2543Smrg * DBE MI Procedure: miDbeAliasBuffers 245706f2543Smrg * 246706f2543Smrg * Description: 247706f2543Smrg * 248706f2543Smrg * This function associates all XIDs of a buffer with the back pixmap 249706f2543Smrg * stored in the window priv. 250706f2543Smrg * 251706f2543Smrg *****************************************************************************/ 252706f2543Smrg 253706f2543Smrgstatic void 254706f2543SmrgmiDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv) 255706f2543Smrg{ 256706f2543Smrg int i; 257706f2543Smrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv = 258706f2543Smrg MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 259706f2543Smrg 260706f2543Smrg for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) 261706f2543Smrg { 262706f2543Smrg ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, 263706f2543Smrg (pointer)pDbeWindowPrivPriv->pBackBuffer); 264706f2543Smrg } 265706f2543Smrg 266706f2543Smrg} /* miDbeAliasBuffers() */ 267706f2543Smrg 268706f2543Smrg 269706f2543Smrg/****************************************************************************** 270706f2543Smrg * 271706f2543Smrg * DBE MI Procedure: miDbeSwapBuffers 272706f2543Smrg * 273706f2543Smrg * Description: 274706f2543Smrg * 275706f2543Smrg * This is the MI function for the DbeSwapBuffers request. 276706f2543Smrg * 277706f2543Smrg *****************************************************************************/ 278706f2543Smrg 279706f2543Smrgstatic int 280706f2543SmrgmiDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo) 281706f2543Smrg{ 282706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 283706f2543Smrg GCPtr pGC; 284706f2543Smrg WindowPtr pWin; 285706f2543Smrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 286706f2543Smrg PixmapPtr pTmpBuffer; 287706f2543Smrg xRectangle clearRect; 288706f2543Smrg 289706f2543Smrg 290706f2543Smrg pWin = swapInfo[0].pWindow; 291706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); 292706f2543Smrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin); 293706f2543Smrg pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 294706f2543Smrg 295706f2543Smrg /* 296706f2543Smrg ********************************************************************** 297706f2543Smrg ** Setup before swap. 298706f2543Smrg ********************************************************************** 299706f2543Smrg */ 300706f2543Smrg 301706f2543Smrg switch(swapInfo[0].swapAction) 302706f2543Smrg { 303706f2543Smrg case XdbeUndefined: 304706f2543Smrg break; 305706f2543Smrg 306706f2543Smrg case XdbeBackground: 307706f2543Smrg break; 308706f2543Smrg 309706f2543Smrg case XdbeUntouched: 310706f2543Smrg ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC); 311706f2543Smrg (*pGC->ops->CopyArea)((DrawablePtr)pWin, 312706f2543Smrg (DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, 313706f2543Smrg pGC, 0, 0, pWin->drawable.width, 314706f2543Smrg pWin->drawable.height, 0, 0); 315706f2543Smrg break; 316706f2543Smrg 317706f2543Smrg case XdbeCopied: 318706f2543Smrg break; 319706f2543Smrg 320706f2543Smrg } 321706f2543Smrg 322706f2543Smrg /* 323706f2543Smrg ********************************************************************** 324706f2543Smrg ** Swap. 325706f2543Smrg ********************************************************************** 326706f2543Smrg */ 327706f2543Smrg 328706f2543Smrg ValidateGC((DrawablePtr)pWin, pGC); 329706f2543Smrg (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, 330706f2543Smrg (DrawablePtr)pWin, pGC, 0, 0, 331706f2543Smrg pWin->drawable.width, pWin->drawable.height, 332706f2543Smrg 0, 0); 333706f2543Smrg 334706f2543Smrg /* 335706f2543Smrg ********************************************************************** 336706f2543Smrg ** Tasks after swap. 337706f2543Smrg ********************************************************************** 338706f2543Smrg */ 339706f2543Smrg 340706f2543Smrg switch(swapInfo[0].swapAction) 341706f2543Smrg { 342706f2543Smrg case XdbeUndefined: 343706f2543Smrg break; 344706f2543Smrg 345706f2543Smrg case XdbeBackground: 346706f2543Smrg if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) 347706f2543Smrg { 348706f2543Smrg ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC); 349706f2543Smrg clearRect.x = 0; 350706f2543Smrg clearRect.y = 0; 351706f2543Smrg clearRect.width = 352706f2543Smrg pDbeWindowPrivPriv->pBackBuffer->drawable.width; 353706f2543Smrg clearRect.height = 354706f2543Smrg pDbeWindowPrivPriv->pBackBuffer->drawable.height; 355706f2543Smrg (*pGC->ops->PolyFillRect)( 356706f2543Smrg (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, 357706f2543Smrg pGC, 1, &clearRect); 358706f2543Smrg } 359706f2543Smrg break; 360706f2543Smrg 361706f2543Smrg case XdbeUntouched: 362706f2543Smrg /* Swap pixmap pointers. */ 363706f2543Smrg pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer; 364706f2543Smrg pDbeWindowPrivPriv->pBackBuffer = 365706f2543Smrg pDbeWindowPrivPriv->pFrontBuffer; 366706f2543Smrg pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer; 367706f2543Smrg 368706f2543Smrg miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv); 369706f2543Smrg 370706f2543Smrg break; 371706f2543Smrg 372706f2543Smrg case XdbeCopied: 373706f2543Smrg break; 374706f2543Smrg 375706f2543Smrg } 376706f2543Smrg 377706f2543Smrg /* Remove the swapped window from the swap information array and decrement 378706f2543Smrg * pNumWindows to indicate to the DIX level how many windows were actually 379706f2543Smrg * swapped. 380706f2543Smrg */ 381706f2543Smrg 382706f2543Smrg if (*pNumWindows > 1) 383706f2543Smrg { 384706f2543Smrg /* We were told to swap more than one window, but we only swapped the 385706f2543Smrg * first one. Remove the first window in the list by moving the last 386706f2543Smrg * window to the beginning. 387706f2543Smrg */ 388706f2543Smrg swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow; 389706f2543Smrg swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction; 390706f2543Smrg 391706f2543Smrg /* Clear the last window information just to be safe. */ 392706f2543Smrg swapInfo[*pNumWindows - 1].pWindow = (WindowPtr)NULL; 393706f2543Smrg swapInfo[*pNumWindows - 1].swapAction = 0; 394706f2543Smrg } 395706f2543Smrg else 396706f2543Smrg { 397706f2543Smrg /* Clear the window information just to be safe. */ 398706f2543Smrg swapInfo[0].pWindow = (WindowPtr)NULL; 399706f2543Smrg swapInfo[0].swapAction = 0; 400706f2543Smrg } 401706f2543Smrg 402706f2543Smrg (*pNumWindows)--; 403706f2543Smrg 404706f2543Smrg FreeScratchGC(pGC); 405706f2543Smrg 406706f2543Smrg return Success; 407706f2543Smrg 408706f2543Smrg} /* miSwapBuffers() */ 409706f2543Smrg 410706f2543Smrg 411706f2543Smrg/****************************************************************************** 412706f2543Smrg * 413706f2543Smrg * DBE MI Procedure: miDbeWinPrivDelete 414706f2543Smrg * 415706f2543Smrg * Description: 416706f2543Smrg * 417706f2543Smrg * This is the MI function for deleting the dbeWindowPrivResType resource. 418706f2543Smrg * This function is invoked indirectly by calling FreeResource() to free 419706f2543Smrg * the resources associated with a DBE buffer ID. There are 5 ways that 420706f2543Smrg * miDbeWinPrivDelete() can be called by FreeResource(). They are: 421706f2543Smrg * 422706f2543Smrg * - A DBE window is destroyed, in which case the DbeDestroyWindow() 423706f2543Smrg * wrapper is invoked. The wrapper calls FreeResource() for all DBE 424706f2543Smrg * buffer IDs. 425706f2543Smrg * 426706f2543Smrg * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources 427706f2543Smrg * after a buffer allocation failure. 428706f2543Smrg * 429706f2543Smrg * - The PositionWindow wrapper, miDbePositionWindow(), calls 430706f2543Smrg * FreeResource() when it fails to create buffers of the new size. 431706f2543Smrg * FreeResource() is called for all DBE buffer IDs. 432706f2543Smrg * 433706f2543Smrg * - FreeClientResources() calls FreeResource() when a client dies or the 434706f2543Smrg * the server resets. 435706f2543Smrg * 436706f2543Smrg * When FreeResource() is called for a DBE buffer ID, the delete function 437706f2543Smrg * for the only other type of DBE resource, dbeDrawableResType, is also 438706f2543Smrg * invoked. This delete function (DbeDrawableDelete) is a NOOP to make 439706f2543Smrg * resource deletion easier. It is not guaranteed which delete function is 440706f2543Smrg * called first. Hence, we will let miDbeWinPrivDelete() free all DBE 441706f2543Smrg * resources. 442706f2543Smrg * 443706f2543Smrg * This function deletes/frees the following stuff associated with 444706f2543Smrg * the window private: 445706f2543Smrg * 446706f2543Smrg * - the ID node in the ID list representing the passed in ID. 447706f2543Smrg * 448706f2543Smrg * In addition, pDbeWindowPriv->nBufferIDs is decremented. 449706f2543Smrg * 450706f2543Smrg * If this function is called for the last/only buffer ID for a window, 451706f2543Smrg * these are additionally deleted/freed: 452706f2543Smrg * 453706f2543Smrg * - the front and back pixmaps 454706f2543Smrg * - the window priv itself 455706f2543Smrg * 456706f2543Smrg *****************************************************************************/ 457706f2543Smrg 458706f2543Smrgstatic void 459706f2543SmrgmiDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId) 460706f2543Smrg{ 461706f2543Smrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 462706f2543Smrg 463706f2543Smrg 464706f2543Smrg if (pDbeWindowPriv->nBufferIDs != 0) 465706f2543Smrg { 466706f2543Smrg /* We still have at least one more buffer ID associated with this 467706f2543Smrg * window. 468706f2543Smrg */ 469706f2543Smrg return; 470706f2543Smrg } 471706f2543Smrg 472706f2543Smrg 473706f2543Smrg /* We have no more buffer IDs associated with this window. We need to 474706f2543Smrg * free some stuff. 475706f2543Smrg */ 476706f2543Smrg 477706f2543Smrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 478706f2543Smrg 479706f2543Smrg /* Destroy the front and back pixmaps. */ 480706f2543Smrg if (pDbeWindowPrivPriv->pFrontBuffer) 481706f2543Smrg { 482706f2543Smrg (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)( 483706f2543Smrg pDbeWindowPrivPriv->pFrontBuffer); 484706f2543Smrg } 485706f2543Smrg if (pDbeWindowPrivPriv->pBackBuffer) 486706f2543Smrg { 487706f2543Smrg (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)( 488706f2543Smrg pDbeWindowPrivPriv->pBackBuffer); 489706f2543Smrg } 490706f2543Smrg 491706f2543Smrg} /* miDbeWinPrivDelete() */ 492706f2543Smrg 493706f2543Smrg 494706f2543Smrg/****************************************************************************** 495706f2543Smrg * 496706f2543Smrg * DBE MI Procedure: miDbePositionWindow 497706f2543Smrg * 498706f2543Smrg * Description: 499706f2543Smrg * 500706f2543Smrg * This function was cloned from miMbxPositionWindow() in mimultibuf.c. 501706f2543Smrg * This function resizes the buffer when the window is resized. 502706f2543Smrg * 503706f2543Smrg *****************************************************************************/ 504706f2543Smrg 505706f2543Smrgstatic Bool 506706f2543SmrgmiDbePositionWindow(WindowPtr pWin, int x, int y) 507706f2543Smrg{ 508706f2543Smrg ScreenPtr pScreen; 509706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 510706f2543Smrg DbeWindowPrivPtr pDbeWindowPriv; 511706f2543Smrg int width, height; 512706f2543Smrg int dx, dy, dw, dh; 513706f2543Smrg int sourcex, sourcey; 514706f2543Smrg int destx, desty; 515706f2543Smrg int savewidth, saveheight; 516706f2543Smrg PixmapPtr pFrontBuffer; 517706f2543Smrg PixmapPtr pBackBuffer; 518706f2543Smrg Bool clear; 519706f2543Smrg GCPtr pGC; 520706f2543Smrg xRectangle clearRect; 521706f2543Smrg Bool ret; 522706f2543Smrg 523706f2543Smrg 524706f2543Smrg /* 525706f2543Smrg ************************************************************************** 526706f2543Smrg ** 1. Unwrap the member routine. 527706f2543Smrg ************************************************************************** 528706f2543Smrg */ 529706f2543Smrg 530706f2543Smrg pScreen = pWin->drawable.pScreen; 531706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 532706f2543Smrg pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; 533706f2543Smrg 534706f2543Smrg /* 535706f2543Smrg ************************************************************************** 536706f2543Smrg ** 2. Do any work necessary before the member routine is called. 537706f2543Smrg ** 538706f2543Smrg ** In this case we do not need to do anything. 539706f2543Smrg ************************************************************************** 540706f2543Smrg */ 541706f2543Smrg 542706f2543Smrg /* 543706f2543Smrg ************************************************************************** 544706f2543Smrg ** 3. Call the member routine, saving its result if necessary. 545706f2543Smrg ************************************************************************** 546706f2543Smrg */ 547706f2543Smrg 548706f2543Smrg ret = (*pScreen->PositionWindow)(pWin, x, y); 549706f2543Smrg 550706f2543Smrg /* 551706f2543Smrg ************************************************************************** 552706f2543Smrg ** 4. Rewrap the member routine, restoring the wrapper value first in case 553706f2543Smrg ** the wrapper (or something that it wrapped) change this value. 554706f2543Smrg ************************************************************************** 555706f2543Smrg */ 556706f2543Smrg 557706f2543Smrg pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 558706f2543Smrg pScreen->PositionWindow = miDbePositionWindow; 559706f2543Smrg 560706f2543Smrg /* 561706f2543Smrg ************************************************************************** 562706f2543Smrg ** 5. Do any work necessary after the member routine has been called. 563706f2543Smrg ************************************************************************** 564706f2543Smrg */ 565706f2543Smrg 566706f2543Smrg if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) 567706f2543Smrg { 568706f2543Smrg return ret; 569706f2543Smrg } 570706f2543Smrg 571706f2543Smrg if (pDbeWindowPriv->width == pWin->drawable.width && 572706f2543Smrg pDbeWindowPriv->height == pWin->drawable.height) 573706f2543Smrg { 574706f2543Smrg return ret; 575706f2543Smrg } 576706f2543Smrg 577706f2543Smrg width = pWin->drawable.width; 578706f2543Smrg height = pWin->drawable.height; 579706f2543Smrg 580706f2543Smrg dx = pWin->drawable.x - pDbeWindowPriv->x; 581706f2543Smrg dy = pWin->drawable.y - pDbeWindowPriv->y; 582706f2543Smrg dw = width - pDbeWindowPriv->width; 583706f2543Smrg dh = height - pDbeWindowPriv->height; 584706f2543Smrg 585706f2543Smrg GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); 586706f2543Smrg 587706f2543Smrg clear = ((pDbeWindowPriv->width < (unsigned short)width ) || 588706f2543Smrg (pDbeWindowPriv->height < (unsigned short)height) || 589706f2543Smrg (pWin->bitGravity == ForgetGravity)); 590706f2543Smrg 591706f2543Smrg sourcex = 0; 592706f2543Smrg sourcey = 0; 593706f2543Smrg savewidth = pDbeWindowPriv->width; 594706f2543Smrg saveheight = pDbeWindowPriv->height; 595706f2543Smrg 596706f2543Smrg /* Clip rectangle to source and destination. */ 597706f2543Smrg if (destx < 0) 598706f2543Smrg { 599706f2543Smrg savewidth += destx; 600706f2543Smrg sourcex -= destx; 601706f2543Smrg destx = 0; 602706f2543Smrg } 603706f2543Smrg 604706f2543Smrg if (destx + savewidth > width) 605706f2543Smrg { 606706f2543Smrg savewidth = width - destx; 607706f2543Smrg } 608706f2543Smrg 609706f2543Smrg if (desty < 0) 610706f2543Smrg { 611706f2543Smrg saveheight += desty; 612706f2543Smrg sourcey -= desty; 613706f2543Smrg desty = 0; 614706f2543Smrg } 615706f2543Smrg 616706f2543Smrg if (desty + saveheight > height) 617706f2543Smrg { 618706f2543Smrg saveheight = height - desty; 619706f2543Smrg } 620706f2543Smrg 621706f2543Smrg pDbeWindowPriv->width = width; 622706f2543Smrg pDbeWindowPriv->height = height; 623706f2543Smrg pDbeWindowPriv->x = pWin->drawable.x; 624706f2543Smrg pDbeWindowPriv->y = pWin->drawable.y; 625706f2543Smrg 626706f2543Smrg pGC = GetScratchGC (pWin->drawable.depth, pScreen); 627706f2543Smrg 628706f2543Smrg if (clear) 629706f2543Smrg { 630706f2543Smrg if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) 631706f2543Smrg { 632706f2543Smrg clearRect.x = 0; 633706f2543Smrg clearRect.y = 0; 634706f2543Smrg clearRect.width = width; 635706f2543Smrg clearRect.height = height; 636706f2543Smrg } 637706f2543Smrg else 638706f2543Smrg { 639706f2543Smrg clear = FALSE; 640706f2543Smrg } 641706f2543Smrg } 642706f2543Smrg 643706f2543Smrg /* Create DBE buffer pixmaps equal to size of resized window. */ 644706f2543Smrg pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, 645706f2543Smrg pWin->drawable.depth, 0); 646706f2543Smrg 647706f2543Smrg pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, 648706f2543Smrg pWin->drawable.depth, 0); 649706f2543Smrg 650706f2543Smrg if (!pFrontBuffer || !pBackBuffer) 651706f2543Smrg { 652706f2543Smrg /* We failed at creating 1 or 2 of the pixmaps. */ 653706f2543Smrg 654706f2543Smrg if (pFrontBuffer) 655706f2543Smrg { 656706f2543Smrg (*pScreen->DestroyPixmap)(pFrontBuffer); 657706f2543Smrg } 658706f2543Smrg 659706f2543Smrg if (pBackBuffer) 660706f2543Smrg { 661706f2543Smrg (*pScreen->DestroyPixmap)(pBackBuffer); 662706f2543Smrg } 663706f2543Smrg 664706f2543Smrg /* Destroy all buffers for this window. */ 665706f2543Smrg while (pDbeWindowPriv) 666706f2543Smrg { 667706f2543Smrg /* DbeWindowPrivDelete() will free the window private if there no 668706f2543Smrg * more buffer IDs associated with this window. 669706f2543Smrg */ 670706f2543Smrg FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); 671706f2543Smrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 672706f2543Smrg } 673706f2543Smrg 674706f2543Smrg FreeScratchGC(pGC); 675706f2543Smrg return FALSE; 676706f2543Smrg } 677706f2543Smrg 678706f2543Smrg else 679706f2543Smrg { 680706f2543Smrg /* Clear out the new DBE buffer pixmaps. */ 681706f2543Smrg 682706f2543Smrg MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; 683706f2543Smrg 684706f2543Smrg 685706f2543Smrg pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); 686706f2543Smrg 687706f2543Smrg /* I suppose this could avoid quite a bit of work if 688706f2543Smrg * it computed the minimal area required. 689706f2543Smrg */ 690706f2543Smrg ValidateGC(&pFrontBuffer->drawable, pGC); 691706f2543Smrg if (clear) 692706f2543Smrg { 693706f2543Smrg (*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1, 694706f2543Smrg &clearRect); 695706f2543Smrg } 696706f2543Smrg /* Copy the contents of the old front pixmap to the new one. */ 697706f2543Smrg if (pWin->bitGravity != ForgetGravity) 698706f2543Smrg { 699706f2543Smrg (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, 700706f2543Smrg (DrawablePtr)pFrontBuffer, pGC, sourcex, 701706f2543Smrg sourcey, savewidth, saveheight, destx, desty); 702706f2543Smrg } 703706f2543Smrg 704706f2543Smrg ValidateGC(&pBackBuffer->drawable, pGC); 705706f2543Smrg if (clear) 706706f2543Smrg { 707706f2543Smrg (*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1, 708706f2543Smrg &clearRect); 709706f2543Smrg } 710706f2543Smrg /* Copy the contents of the old back pixmap to the new one. */ 711706f2543Smrg if (pWin->bitGravity != ForgetGravity) 712706f2543Smrg { 713706f2543Smrg (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, 714706f2543Smrg (DrawablePtr)pBackBuffer, pGC, sourcex, 715706f2543Smrg sourcey, savewidth, saveheight, destx, desty); 716706f2543Smrg } 717706f2543Smrg 718706f2543Smrg /* Destroy the old pixmaps, and point the DBE window priv to the new 719706f2543Smrg * pixmaps. 720706f2543Smrg */ 721706f2543Smrg 722706f2543Smrg (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); 723706f2543Smrg (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer); 724706f2543Smrg 725706f2543Smrg pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer; 726706f2543Smrg pDbeWindowPrivPriv->pBackBuffer = pBackBuffer; 727706f2543Smrg 728706f2543Smrg /* Make sure all XID are associated with the new back pixmap. */ 729706f2543Smrg miDbeAliasBuffers(pDbeWindowPriv); 730706f2543Smrg 731706f2543Smrg FreeScratchGC(pGC); 732706f2543Smrg } 733706f2543Smrg 734706f2543Smrg return ret; 735706f2543Smrg 736706f2543Smrg} /* miDbePositionWindow() */ 737706f2543Smrg 738706f2543Smrg 739706f2543Smrg/****************************************************************************** 740706f2543Smrg * 741706f2543Smrg * DBE MI Procedure: miDbeResetProc 742706f2543Smrg * 743706f2543Smrg * Description: 744706f2543Smrg * 745706f2543Smrg * This function is called from DbeResetProc(), which is called at the end 746706f2543Smrg * of every server generation. This function peforms any MI-specific 747706f2543Smrg * shutdown tasks. 748706f2543Smrg * 749706f2543Smrg *****************************************************************************/ 750706f2543Smrg 751706f2543Smrgstatic void 752706f2543SmrgmiDbeResetProc(ScreenPtr pScreen) 753706f2543Smrg{ 754706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 755706f2543Smrg 756706f2543Smrg 757706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 758706f2543Smrg 759706f2543Smrg /* Unwrap wrappers */ 760706f2543Smrg pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; 761706f2543Smrg 762706f2543Smrg} /* miDbeResetProc() */ 763706f2543Smrg 764706f2543Smrg 765706f2543Smrg/****************************************************************************** 766706f2543Smrg * 767706f2543Smrg * DBE MI Procedure: miDbeInit 768706f2543Smrg * 769706f2543Smrg * Description: 770706f2543Smrg * 771706f2543Smrg * This is the MI initialization function called by DbeExtensionInit(). 772706f2543Smrg * 773706f2543Smrg *****************************************************************************/ 774706f2543Smrg 775706f2543SmrgBool 776706f2543SmrgmiDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv) 777706f2543Smrg{ 778706f2543Smrg if (!dixRegisterPrivateKey(&miDbeWindowPrivPrivKeyRec, PRIVATE_DBE_WINDOW, 779706f2543Smrg sizeof(MiDbeWindowPrivPrivRec))) 780706f2543Smrg return FALSE; 781706f2543Smrg 782706f2543Smrg /* Wrap functions. */ 783706f2543Smrg pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 784706f2543Smrg pScreen->PositionWindow = miDbePositionWindow; 785706f2543Smrg 786706f2543Smrg /* Initialize the per-screen DBE function pointers. */ 787706f2543Smrg pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo; 788706f2543Smrg pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName; 789706f2543Smrg pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers; 790706f2543Smrg pDbeScreenPriv->BeginIdiom = 0; 791706f2543Smrg pDbeScreenPriv->EndIdiom = 0; 792706f2543Smrg pDbeScreenPriv->ResetProc = miDbeResetProc; 793706f2543Smrg pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete; 794706f2543Smrg 795706f2543Smrg return TRUE; 796706f2543Smrg 797706f2543Smrg} /* miDbeInit() */ 798