1/****************************************************************************** 2 * 3 * Copyright (c) 1994, 1995 Hewlett-Packard Company 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Except as contained in this notice, the name of the Hewlett-Packard 25 * Company shall not be used in advertising or otherwise to promote the 26 * sale, use or other dealings in this Software without prior written 27 * authorization from the Hewlett-Packard Company. 28 * 29 * Machine-independent DBE code 30 * 31 *****************************************************************************/ 32 33/* INCLUDES */ 34 35#ifdef HAVE_DIX_CONFIG_H 36#include <dix-config.h> 37#endif 38 39#include <X11/X.h> 40#include <X11/Xproto.h> 41#include "misc.h" 42#include "os.h" 43#include "windowstr.h" 44#include "scrnintstr.h" 45#include "pixmapstr.h" 46#include "extnsionst.h" 47#include "dixstruct.h" 48#include "resource.h" 49#include "opaque.h" 50#include "dbestruct.h" 51#include "regionstr.h" 52#include "gcstruct.h" 53#include "inputstr.h" 54#include "midbe.h" 55#include "xace.h" 56 57#include <stdio.h> 58 59 60/****************************************************************************** 61 * 62 * DBE MI Procedure: miDbeGetVisualInfo 63 * 64 * Description: 65 * 66 * This is the MI function for the DbeGetVisualInfo request. This function 67 * is called through pDbeScreenPriv->GetVisualInfo. This function is also 68 * called for the DbeAllocateBackBufferName request at the extension level; 69 * it is called by ProcDbeAllocateBackBufferName() in dbe.c. 70 * 71 * If memory allocation fails or we can not get the visual info, this 72 * function returns FALSE. Otherwise, it returns TRUE for success. 73 * 74 *****************************************************************************/ 75 76static Bool 77miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo) 78{ 79 register int i, j, k; 80 register int count; 81 DepthPtr pDepth; 82 XdbeVisualInfo *visInfo; 83 84 /* Determine number of visuals for this screen. */ 85 for (i = 0, count = 0; i < pScreen->numDepths; i++) { 86 count += pScreen->allowedDepths[i].numVids; 87 } 88 89 /* Allocate an array of XdbeVisualInfo items. */ 90 if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) { 91 return FALSE; /* memory alloc failure */ 92 } 93 94 for (i = 0, k = 0; i < pScreen->numDepths; i++) { 95 /* For each depth of this screen, get visual information. */ 96 97 pDepth = &pScreen->allowedDepths[i]; 98 99 for (j = 0; j < pDepth->numVids; j++) { 100 /* For each visual for this depth of this screen, get visual ID 101 * and visual depth. Since this is MI code, we will always return 102 * the same performance level for all visuals (0). A higher 103 * performance level value indicates higher performance. 104 */ 105 visInfo[k].visual = pDepth->vids[j]; 106 visInfo[k].depth = pDepth->depth; 107 visInfo[k].perflevel = 0; 108 k++; 109 } 110 } 111 112 /* Record the number of visuals and point visual_depth to 113 * the array of visual info. 114 */ 115 pScrVisInfo->count = count; 116 pScrVisInfo->visinfo = visInfo; 117 118 return TRUE; /* success */ 119 120} /* miDbeGetVisualInfo() */ 121 122/****************************************************************************** 123 * 124 * DBE MI Procedure: miAllocBackBufferName 125 * 126 * Description: 127 * 128 * This is the MI function for the DbeAllocateBackBufferName request. 129 * 130 *****************************************************************************/ 131 132static int 133miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction) 134{ 135 ScreenPtr pScreen; 136 DbeWindowPrivPtr pDbeWindowPriv; 137 DbeScreenPrivPtr pDbeScreenPriv; 138 GCPtr pGC; 139 xRectangle clearRect; 140 int rc; 141 142 pScreen = pWin->drawable.pScreen; 143 pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 144 145 if (pDbeWindowPriv->nBufferIDs == 0) { 146 /* There is no buffer associated with the window. 147 * We have to create the window priv priv. Remember, the window 148 * priv was created at the DIX level, so all we need to do is 149 * create the priv priv and attach it to the priv. 150 */ 151 152 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 153 154 /* Get a front pixmap. */ 155 if (!(pDbeWindowPriv->pFrontBuffer = 156 (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, 157 pDbeWindowPriv->height, 158 pWin->drawable.depth, 0))) { 159 return BadAlloc; 160 } 161 162 /* Get a back pixmap. */ 163 if (!(pDbeWindowPriv->pBackBuffer = 164 (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, 165 pDbeWindowPriv->height, 166 pWin->drawable.depth, 0))) { 167 (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); 168 return BadAlloc; 169 } 170 171 /* Security creation/labeling check. */ 172 rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId, 173 dbeDrawableResType, pDbeWindowPriv->pBackBuffer, 174 RT_WINDOW, pWin, DixCreateAccess); 175 176 /* Make the back pixmap a DBE drawable resource. */ 177 if (rc != Success || !AddResource(bufId, dbeDrawableResType, 178 pDbeWindowPriv->pBackBuffer)) { 179 /* free the buffer and the drawable resource */ 180 FreeResource(bufId, RT_NONE); 181 return (rc == Success) ? BadAlloc : rc; 182 } 183 184 /* Clear the back buffer. */ 185 pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 186 if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { 187 ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); 188 clearRect.x = clearRect.y = 0; 189 clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; 190 clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; 191 (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> 192 pBackBuffer, pGC, 1, &clearRect); 193 } 194 FreeScratchGC(pGC); 195 196 } /* if no buffer associated with the window */ 197 198 else { 199 /* A buffer is already associated with the window. 200 * Place the new buffer ID information at the head of the ID list. 201 */ 202 203 /* Associate the new ID with an existing pixmap. */ 204 if (!AddResource(bufId, dbeDrawableResType, 205 (void *) pDbeWindowPriv->pBackBuffer)) { 206 return BadAlloc; 207 } 208 209 } 210 211 return Success; 212 213} /* miDbeAllocBackBufferName() */ 214 215/****************************************************************************** 216 * 217 * DBE MI Procedure: miDbeAliasBuffers 218 * 219 * Description: 220 * 221 * This function associates all XIDs of a buffer with the back pixmap 222 * stored in the window priv. 223 * 224 *****************************************************************************/ 225 226static void 227miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv) 228{ 229 int i; 230 231 for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) { 232 ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, 233 (void *) pDbeWindowPriv->pBackBuffer); 234 } 235 236} /* miDbeAliasBuffers() */ 237 238/****************************************************************************** 239 * 240 * DBE MI Procedure: miDbeSwapBuffers 241 * 242 * Description: 243 * 244 * This is the MI function for the DbeSwapBuffers request. 245 * 246 *****************************************************************************/ 247 248static int 249miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo) 250{ 251 DbeScreenPrivPtr pDbeScreenPriv; 252 DbeWindowPrivPtr pDbeWindowPriv; 253 GCPtr pGC; 254 WindowPtr pWin; 255 PixmapPtr pTmpBuffer; 256 xRectangle clearRect; 257 258 pWin = swapInfo[0].pWindow; 259 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); 260 pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 261 pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 262 263 /* 264 ********************************************************************** 265 ** Setup before swap. 266 ********************************************************************** 267 */ 268 269 switch (swapInfo[0].swapAction) { 270 case XdbeUndefined: 271 break; 272 273 case XdbeBackground: 274 break; 275 276 case XdbeUntouched: 277 ValidateGC((DrawablePtr) pDbeWindowPriv->pFrontBuffer, pGC); 278 (*pGC->ops->CopyArea) ((DrawablePtr) pWin, 279 (DrawablePtr) pDbeWindowPriv->pFrontBuffer, 280 pGC, 0, 0, pWin->drawable.width, 281 pWin->drawable.height, 0, 0); 282 break; 283 284 case XdbeCopied: 285 break; 286 287 } 288 289 /* 290 ********************************************************************** 291 ** Swap. 292 ********************************************************************** 293 */ 294 295 ValidateGC((DrawablePtr) pWin, pGC); 296 (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, 297 (DrawablePtr) pWin, pGC, 0, 0, 298 pWin->drawable.width, pWin->drawable.height, 0, 0); 299 300 /* 301 ********************************************************************** 302 ** Tasks after swap. 303 ********************************************************************** 304 */ 305 306 switch (swapInfo[0].swapAction) { 307 case XdbeUndefined: 308 break; 309 310 case XdbeBackground: 311 if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { 312 ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); 313 clearRect.x = 0; 314 clearRect.y = 0; 315 clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; 316 clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; 317 (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> 318 pBackBuffer, pGC, 1, &clearRect); 319 } 320 break; 321 322 case XdbeUntouched: 323 /* Swap pixmap pointers. */ 324 pTmpBuffer = pDbeWindowPriv->pBackBuffer; 325 pDbeWindowPriv->pBackBuffer = pDbeWindowPriv->pFrontBuffer; 326 pDbeWindowPriv->pFrontBuffer = pTmpBuffer; 327 328 miDbeAliasBuffers(pDbeWindowPriv); 329 330 break; 331 332 case XdbeCopied: 333 break; 334 335 } 336 337 /* Remove the swapped window from the swap information array and decrement 338 * pNumWindows to indicate to the DIX level how many windows were actually 339 * swapped. 340 */ 341 342 if (*pNumWindows > 1) { 343 /* We were told to swap more than one window, but we only swapped the 344 * first one. Remove the first window in the list by moving the last 345 * window to the beginning. 346 */ 347 swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow; 348 swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction; 349 350 /* Clear the last window information just to be safe. */ 351 swapInfo[*pNumWindows - 1].pWindow = (WindowPtr) NULL; 352 swapInfo[*pNumWindows - 1].swapAction = 0; 353 } 354 else { 355 /* Clear the window information just to be safe. */ 356 swapInfo[0].pWindow = (WindowPtr) NULL; 357 swapInfo[0].swapAction = 0; 358 } 359 360 (*pNumWindows)--; 361 362 FreeScratchGC(pGC); 363 364 return Success; 365 366} /* miSwapBuffers() */ 367 368/****************************************************************************** 369 * 370 * DBE MI Procedure: miDbeWinPrivDelete 371 * 372 * Description: 373 * 374 * This is the MI function for deleting the dbeWindowPrivResType resource. 375 * This function is invoked indirectly by calling FreeResource() to free 376 * the resources associated with a DBE buffer ID. There are 5 ways that 377 * miDbeWinPrivDelete() can be called by FreeResource(). They are: 378 * 379 * - A DBE window is destroyed, in which case the DbeDestroyWindow() 380 * wrapper is invoked. The wrapper calls FreeResource() for all DBE 381 * buffer IDs. 382 * 383 * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources 384 * after a buffer allocation failure. 385 * 386 * - The PositionWindow wrapper, miDbePositionWindow(), calls 387 * FreeResource() when it fails to create buffers of the new size. 388 * FreeResource() is called for all DBE buffer IDs. 389 * 390 * - FreeClientResources() calls FreeResource() when a client dies or the 391 * the server resets. 392 * 393 * When FreeResource() is called for a DBE buffer ID, the delete function 394 * for the only other type of DBE resource, dbeDrawableResType, is also 395 * invoked. This delete function (DbeDrawableDelete) is a NOOP to make 396 * resource deletion easier. It is not guaranteed which delete function is 397 * called first. Hence, we will let miDbeWinPrivDelete() free all DBE 398 * resources. 399 * 400 * This function deletes/frees the following stuff associated with 401 * the window private: 402 * 403 * - the ID node in the ID list representing the passed in ID. 404 * 405 * In addition, pDbeWindowPriv->nBufferIDs is decremented. 406 * 407 * If this function is called for the last/only buffer ID for a window, 408 * these are additionally deleted/freed: 409 * 410 * - the front and back pixmaps 411 * - the window priv itself 412 * 413 *****************************************************************************/ 414 415static void 416miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId) 417{ 418 if (pDbeWindowPriv->nBufferIDs != 0) { 419 /* We still have at least one more buffer ID associated with this 420 * window. 421 */ 422 return; 423 } 424 425 /* We have no more buffer IDs associated with this window. We need to 426 * free some stuff. 427 */ 428 429 /* Destroy the front and back pixmaps. */ 430 if (pDbeWindowPriv->pFrontBuffer) { 431 (*pDbeWindowPriv->pWindow->drawable.pScreen-> 432 DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); 433 } 434 if (pDbeWindowPriv->pBackBuffer) { 435 (*pDbeWindowPriv->pWindow->drawable.pScreen-> 436 DestroyPixmap) (pDbeWindowPriv->pBackBuffer); 437 } 438} /* miDbeWinPrivDelete() */ 439 440/****************************************************************************** 441 * 442 * DBE MI Procedure: miDbePositionWindow 443 * 444 * Description: 445 * 446 * This function was cloned from miMbxPositionWindow() in mimultibuf.c. 447 * This function resizes the buffer when the window is resized. 448 * 449 *****************************************************************************/ 450 451static Bool 452miDbePositionWindow(WindowPtr pWin, int x, int y) 453{ 454 ScreenPtr pScreen; 455 DbeScreenPrivPtr pDbeScreenPriv; 456 DbeWindowPrivPtr pDbeWindowPriv; 457 int width, height; 458 int dx, dy, dw, dh; 459 int sourcex, sourcey; 460 int destx, desty; 461 int savewidth, saveheight; 462 PixmapPtr pFrontBuffer; 463 PixmapPtr pBackBuffer; 464 Bool clear; 465 GCPtr pGC; 466 xRectangle clearRect; 467 Bool ret; 468 469 /* 470 ************************************************************************** 471 ** 1. Unwrap the member routine. 472 ************************************************************************** 473 */ 474 475 pScreen = pWin->drawable.pScreen; 476 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 477 pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; 478 479 /* 480 ************************************************************************** 481 ** 2. Do any work necessary before the member routine is called. 482 ** 483 ** In this case we do not need to do anything. 484 ************************************************************************** 485 */ 486 487 /* 488 ************************************************************************** 489 ** 3. Call the member routine, saving its result if necessary. 490 ************************************************************************** 491 */ 492 493 ret = (*pScreen->PositionWindow) (pWin, x, y); 494 495 /* 496 ************************************************************************** 497 ** 4. Rewrap the member routine, restoring the wrapper value first in case 498 ** the wrapper (or something that it wrapped) change this value. 499 ************************************************************************** 500 */ 501 502 pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 503 pScreen->PositionWindow = miDbePositionWindow; 504 505 /* 506 ************************************************************************** 507 ** 5. Do any work necessary after the member routine has been called. 508 ************************************************************************** 509 */ 510 511 if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) { 512 return ret; 513 } 514 515 if (pDbeWindowPriv->width == pWin->drawable.width && 516 pDbeWindowPriv->height == pWin->drawable.height) { 517 return ret; 518 } 519 520 width = pWin->drawable.width; 521 height = pWin->drawable.height; 522 523 dx = pWin->drawable.x - pDbeWindowPriv->x; 524 dy = pWin->drawable.y - pDbeWindowPriv->y; 525 dw = width - pDbeWindowPriv->width; 526 dh = height - pDbeWindowPriv->height; 527 528 GravityTranslate(0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); 529 530 clear = ((pDbeWindowPriv->width < (unsigned short) width) || 531 (pDbeWindowPriv->height < (unsigned short) height) || 532 (pWin->bitGravity == ForgetGravity)); 533 534 sourcex = 0; 535 sourcey = 0; 536 savewidth = pDbeWindowPriv->width; 537 saveheight = pDbeWindowPriv->height; 538 539 /* Clip rectangle to source and destination. */ 540 if (destx < 0) { 541 savewidth += destx; 542 sourcex -= destx; 543 destx = 0; 544 } 545 546 if (destx + savewidth > width) { 547 savewidth = width - destx; 548 } 549 550 if (desty < 0) { 551 saveheight += desty; 552 sourcey -= desty; 553 desty = 0; 554 } 555 556 if (desty + saveheight > height) { 557 saveheight = height - desty; 558 } 559 560 pDbeWindowPriv->width = width; 561 pDbeWindowPriv->height = height; 562 pDbeWindowPriv->x = pWin->drawable.x; 563 pDbeWindowPriv->y = pWin->drawable.y; 564 565 pGC = GetScratchGC(pWin->drawable.depth, pScreen); 566 567 if (clear) { 568 if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { 569 clearRect.x = 0; 570 clearRect.y = 0; 571 clearRect.width = width; 572 clearRect.height = height; 573 } 574 else { 575 clear = FALSE; 576 } 577 } 578 579 /* Create DBE buffer pixmaps equal to size of resized window. */ 580 pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, 581 pWin->drawable.depth, 0); 582 583 pBackBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, 584 pWin->drawable.depth, 0); 585 586 if (!pFrontBuffer || !pBackBuffer) { 587 /* We failed at creating 1 or 2 of the pixmaps. */ 588 589 if (pFrontBuffer) { 590 (*pScreen->DestroyPixmap) (pFrontBuffer); 591 } 592 593 if (pBackBuffer) { 594 (*pScreen->DestroyPixmap) (pBackBuffer); 595 } 596 597 /* Destroy all buffers for this window. */ 598 while (pDbeWindowPriv) { 599 /* DbeWindowPrivDelete() will free the window private if there no 600 * more buffer IDs associated with this window. 601 */ 602 FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); 603 pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 604 } 605 606 FreeScratchGC(pGC); 607 return FALSE; 608 } 609 610 else { 611 /* Clear out the new DBE buffer pixmaps. */ 612 613 /* I suppose this could avoid quite a bit of work if 614 * it computed the minimal area required. 615 */ 616 ValidateGC(&pFrontBuffer->drawable, pGC); 617 if (clear) { 618 (*pGC->ops->PolyFillRect) ((DrawablePtr) pFrontBuffer, pGC, 1, 619 &clearRect); 620 } 621 /* Copy the contents of the old front pixmap to the new one. */ 622 if (pWin->bitGravity != ForgetGravity) { 623 (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pFrontBuffer, 624 (DrawablePtr) pFrontBuffer, pGC, 625 sourcex, sourcey, savewidth, saveheight, 626 destx, desty); 627 } 628 629 ValidateGC(&pBackBuffer->drawable, pGC); 630 if (clear) { 631 (*pGC->ops->PolyFillRect) ((DrawablePtr) pBackBuffer, pGC, 1, 632 &clearRect); 633 } 634 /* Copy the contents of the old back pixmap to the new one. */ 635 if (pWin->bitGravity != ForgetGravity) { 636 (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, 637 (DrawablePtr) pBackBuffer, pGC, 638 sourcex, sourcey, savewidth, saveheight, 639 destx, desty); 640 } 641 642 /* Destroy the old pixmaps, and point the DBE window priv to the new 643 * pixmaps. 644 */ 645 646 (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); 647 (*pScreen->DestroyPixmap) (pDbeWindowPriv->pBackBuffer); 648 649 pDbeWindowPriv->pFrontBuffer = pFrontBuffer; 650 pDbeWindowPriv->pBackBuffer = pBackBuffer; 651 652 /* Make sure all XID are associated with the new back pixmap. */ 653 miDbeAliasBuffers(pDbeWindowPriv); 654 655 FreeScratchGC(pGC); 656 } 657 658 return ret; 659 660} /* miDbePositionWindow() */ 661 662/****************************************************************************** 663 * 664 * DBE MI Procedure: miDbeInit 665 * 666 * Description: 667 * 668 * This is the MI initialization function called by DbeExtensionInit(). 669 * 670 *****************************************************************************/ 671 672Bool 673miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv) 674{ 675 /* Wrap functions. */ 676 pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; 677 pScreen->PositionWindow = miDbePositionWindow; 678 679 /* Initialize the per-screen DBE function pointers. */ 680 pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo; 681 pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName; 682 pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers; 683 pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete; 684 685 return TRUE; 686 687} /* miDbeInit() */ 688