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