dbe.c 45.5 KB
Newer Older
1
/******************************************************************************
2
 *
3 4 5 6 7 8 9 10 11
 * Copyright (c) 1994, 1995  Hewlett-Packard Company
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
12
 *
13 14
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
15
 *
16 17 18 19 20 21 22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 *
24 25 26 27
 * Except as contained in this notice, the name of the Hewlett-Packard
 * Company shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization from the Hewlett-Packard Company.
28
 *
29 30 31 32 33 34
 *     DIX DBE code
 *
 *****************************************************************************/

/* INCLUDES */

35 36 37 38
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif

39
#include <string.h>
40
#include <stdint.h>
41 42
#include <X11/X.h>
#include <X11/Xproto.h>
43 44
#include "scrnintstr.h"
#include "extnsionst.h"
45
#include "extinit.h"
46 47 48 49 50
#include "gcstruct.h"
#include "dixstruct.h"
#define NEED_DBE_PROTOCOL
#include "dbestruct.h"
#include "midbe.h"
51
#include "xace.h"
52 53 54

/* GLOBALS */

55 56 57
/* These are globals for use by DDX */
DevPrivateKeyRec dbeScreenPrivKeyRec;
DevPrivateKeyRec dbeWindowPrivKeyRec;
58

59
/* These are globals for use by DDX */
60 61
RESTYPE dbeDrawableResType;
RESTYPE dbeWindowPrivResType;
62 63

/* Used to generate DBE's BadBuffer error. */
64
static int dbeErrorBase;
65 66 67 68 69 70 71 72 73 74 75 76 77

/******************************************************************************
 *
 * DBE DIX Procedure: DbeStubScreen
 *
 * Description:
 *
 *     This is function stubs the function pointers in the given DBE screen
 *     private and increments the number of stubbed screens.
 *
 *****************************************************************************/

static void
78
DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
79 80 81 82 83 84 85 86 87 88 89
{
    /* Stub DIX. */
    pDbeScreenPriv->SetupBackgroundPainter = NULL;

    /* Do not unwrap PositionWindow nor DestroyWindow.  If the DDX
     * initialization function failed, we assume that it did not wrap
     * PositionWindow.  Also, DestroyWindow is only wrapped if the DDX
     * initialization function succeeded.
     */

    /* Stub DDX. */
90
    pDbeScreenPriv->GetVisualInfo = NULL;
91
    pDbeScreenPriv->AllocBackBufferName = NULL;
92 93
    pDbeScreenPriv->SwapBuffers = NULL;
    pDbeScreenPriv->WinPrivDelete = NULL;
94 95 96

    (*nStubbedScreens)++;

97
}                               /* DbeStubScreen() */
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

/******************************************************************************
 *
 * DBE DIX Procedure: ProcDbeGetVersion
 *
 * Description:
 *
 *     This function is for processing a DbeGetVersion request.
 *     This request returns the major and minor version numbers of this
 *     extension.
 *
 * Return Values:
 *
 *     Success
 *
 *****************************************************************************/

static int
116
ProcDbeGetVersion(ClientPtr client)
117
{
118
    /* REQUEST(xDbeGetVersionReq); */
119 120 121 122 123 124 125
    xDbeGetVersionReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .majorVersion = DBE_MAJOR_VERSION,
        .minorVersion = DBE_MINOR_VERSION
    };
126 127 128

    REQUEST_SIZE_MATCH(xDbeGetVersionReq);

129
    if (client->swapped) {
130
        swaps(&rep.sequenceNumber);
131 132
    }

133
    WriteToClient(client, sizeof(xDbeGetVersionReply), &rep);
134

135
    return Success;
136

137
}                               /* ProcDbeGetVersion() */
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

/******************************************************************************
 *
 * DBE DIX Procedure: ProcDbeAllocateBackBufferName
 *
 * Description:
 *
 *     This function is for processing a DbeAllocateBackBufferName request.
 *     This request allocates a drawable ID used to refer to the back buffer
 *     of a window.
 *
 * Return Values:
 *
 *     BadAlloc    - server can not allocate resources
 *     BadIDChoice - id is out of range for client; id is already in use
 *     BadMatch    - window is not an InputOutput window;
 *                   visual of window is not on list returned by
155
 *                   DBEGetVisualInfo;
156 157 158 159 160 161 162
 *     BadValue    - invalid swap action is specified
 *     BadWindow   - window is not a valid window
 *     Success
 *
 *****************************************************************************/

static int
163
ProcDbeAllocateBackBufferName(ClientPtr client)
164 165
{
    REQUEST(xDbeAllocateBackBufferNameReq);
166 167 168 169 170 171 172 173 174 175
    WindowPtr pWin;
    DbeScreenPrivPtr pDbeScreenPriv;
    DbeWindowPrivPtr pDbeWindowPriv;
    XdbeScreenVisualInfo scrVisInfo;
    register int i;
    Bool visualMatched = FALSE;
    xDbeSwapAction swapAction;
    VisualID visual;
    int status;
    int add_index;
176 177 178 179

    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);

    /* The window must be valid. */
180
    status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
181
    if (status != Success)
182
        return status;
183 184

    /* The window must be InputOutput. */
185 186
    if (pWin->drawable.class != InputOutput) {
        return BadMatch;
187 188 189
    }

    /* The swap action must be valid. */
190 191
    swapAction = stuff->swapAction;     /* use local var for performance. */
    if ((swapAction != XdbeUndefined) &&
192
        (swapAction != XdbeBackground) &&
193
        (swapAction != XdbeUntouched) && (swapAction != XdbeCopied)) {
194
        return BadValue;
195 196 197 198 199 200 201 202 203 204
    }

    /* The id must be in range and not already in use. */
    LEGAL_NEW_RESOURCE(stuff->buffer, client);

    /* The visual of the window must be in the list returned by
     * GetVisualInfo.
     */
    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
    if (!pDbeScreenPriv->GetVisualInfo)
205
        return BadMatch;        /* screen doesn't support double buffering */
206

207
    if (!(*pDbeScreenPriv->GetVisualInfo) (pWin->drawable.pScreen, &scrVisInfo)) {
208
        /* GetVisualInfo() failed to allocate visual info data. */
209
        return BadAlloc;
210 211 212 213
    }

    /* See if the window's visual is on the list. */
    visual = wVisual(pWin);
214 215 216 217
    for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++) {
        if (scrVisInfo.visinfo[i].visual == visual) {
            visualMatched = TRUE;
        }
218 219 220
    }

    /* Free what was allocated by the GetVisualInfo() call above. */
221
    free(scrVisInfo.visinfo);
222

223 224
    if (!visualMatched) {
        return BadMatch;
225 226
    }

227
    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL) {
228 229 230 231
        /* There is no buffer associated with the window.
         * Allocate a window priv.
         */

232
        pDbeWindowPriv = calloc(1, sizeof(DbeWindowPrivRec));
233
        if (!pDbeWindowPriv)
234
            return BadAlloc;
235 236

        /* Fill out window priv information. */
237 238 239 240 241 242
        pDbeWindowPriv->pWindow = pWin;
        pDbeWindowPriv->width = pWin->drawable.width;
        pDbeWindowPriv->height = pWin->drawable.height;
        pDbeWindowPriv->x = pWin->drawable.x;
        pDbeWindowPriv->y = pWin->drawable.y;
        pDbeWindowPriv->nBufferIDs = 0;
243 244 245 246

        /* Set the buffer ID array pointer to the initial (static) array). */
        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;

247
        /* Initialize the buffer ID list. */
248 249
        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
        pDbeWindowPriv->IDs[0] = stuff->buffer;
250 251

        add_index = 0;
252
        for (i = 0; i < DBE_INIT_MAX_IDS; i++) {
253 254 255 256
            pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
        }

        /* Actually connect the window priv to the window. */
257
        dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
258

259
    }                           /* if -- There is no buffer associated with the window. */
260

261
    else {
262 263 264 265 266 267
        /* A buffer is already associated with the window.
         * Add the new buffer ID to the array, reallocating the array memory
         * if necessary.
         */

        /* Determine if there is a free element in the ID array. */
268 269
        for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++) {
            if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT) {
270 271 272 273
                /* There is still room in the ID array. */
                break;
            }
        }
274 275

        if (i == pDbeWindowPriv->maxAvailableIDs) {
276
            /* No more room in the ID array -- reallocate another array. */
277
            XID *pIDs;
278 279

            /* Setup an array pointer for the realloc operation below. */
280
            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) {
281 282 283
                /* We will malloc a new array. */
                pIDs = NULL;
            }
284
            else {
285 286 287 288 289
                /* We will realloc a new array. */
                pIDs = pDbeWindowPriv->IDs;
            }

            /* malloc/realloc a new array and initialize all elements to 0. */
290 291 292 293
            pDbeWindowPriv->IDs =
                reallocarray(pIDs,
                             pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS,
                             sizeof(XID));
294
            if (!pDbeWindowPriv->IDs) {
295
                return BadAlloc;
296 297 298 299 300
            }
            memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
                   (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
                    pDbeWindowPriv->nBufferIDs) * sizeof(XID));

301
            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) {
302 303 304 305 306 307 308 309 310 311 312
                /* We just went from using the initial (static) array to a
                 * newly allocated array.  Copy the IDs from the initial array
                 * to the new array.
                 */
                memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
                       DBE_INIT_MAX_IDS * sizeof(XID));
            }

            pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
        }

313
        add_index = i;
314

315
    }                           /* else -- A buffer is already associated with the window. */
316 317

    /* Call the DDX routine to allocate the back buffer. */
318 319
    status = (*pDbeScreenPriv->AllocBackBufferName) (pWin, stuff->buffer,
                                                     stuff->swapAction);
320

321 322
    if (status == Success) {
        pDbeWindowPriv->IDs[add_index] = stuff->buffer;
323
        if (!AddResource(stuff->buffer, dbeWindowPrivResType,
324
                         (void *) pDbeWindowPriv)) {
325 326 327 328 329 330 331
            pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;

            if (pDbeWindowPriv->nBufferIDs == 0) {
                status = BadAlloc;
                goto out_free;
            }
        }
332 333
    }
    else {
334 335 336
        /* The DDX buffer allocation routine failed for the first buffer of
         * this window.
         */
337 338 339
        if (pDbeWindowPriv->nBufferIDs == 0) {
            goto out_free;
        }
340 341 342 343 344 345 346 347
    }

    /* Increment the number of buffers (XIDs) associated with this window. */
    pDbeWindowPriv->nBufferIDs++;

    /* Set swap action on all calls. */
    pDbeWindowPriv->swapAction = stuff->swapAction;

348
    return status;
349

350
 out_free:
351
    dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
352
    free(pDbeWindowPriv);
353
    return status;
354

355
}                               /* ProcDbeAllocateBackBufferName() */
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374

/******************************************************************************
 *
 * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
 *
 * Description:
 *
 *     This function is for processing a DbeDeallocateBackBufferName request.
 *     This request frees a drawable ID that was obtained by a
 *     DbeAllocateBackBufferName request.
 *
 * Return Values:
 *
 *     BadBuffer - buffer to deallocate is not associated with a window
 *     Success
 *
 *****************************************************************************/

static int
375
ProcDbeDeallocateBackBufferName(ClientPtr client)
376 377
{
    REQUEST(xDbeDeallocateBackBufferNameReq);
378 379
    DbeWindowPrivPtr pDbeWindowPriv;
    int rc, i;
380
    void *val;
381 382 383 384

    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);

    /* Buffer name must be valid */
385
    rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer,
386 387
                                 dbeWindowPrivResType, client,
                                 DixDestroyAccess);
388
    if (rc != Success)
389
        return rc;
390 391

    rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
392
                                 client, DixDestroyAccess);
393
    if (rc != Success)
394
        return rc;
395 396 397 398 399 400

    /* Make sure that the id is valid for the window.
     * This is paranoid code since we already looked up the ID by type
     * above.
     */

401
    for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) {
402
        /* Loop through the ID list to find the ID. */
403
        if (pDbeWindowPriv->IDs[i] == stuff->buffer) {
404 405 406 407
            break;
        }
    }

408
    if (i == pDbeWindowPriv->nBufferIDs) {
409 410
        /* We did not find the ID in the ID list. */
        client->errorValue = stuff->buffer;
411
        return dbeErrorBase + DbeBadBuffer;
412 413 414 415
    }

    FreeResource(stuff->buffer, RT_NONE);

416
    return Success;
417

418
}                               /* ProcDbeDeallocateBackBufferName() */
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443

/******************************************************************************
 *
 * DBE DIX Procedure: ProcDbeSwapBuffers
 *
 * Description:
 *
 *     This function is for processing a DbeSwapBuffers request.
 *     This request swaps the buffers for all windows listed, applying the
 *     appropriate swap action for each window.
 *
 * Return Values:
 *
 *     BadAlloc  - local allocation failed; this return value is not defined
 *                 by the protocol
 *     BadMatch  - a window in request is not double-buffered; a window in
 *                 request is listed more than once
 *     BadValue  - invalid swap action is specified; no swap action is
 *                 specified
 *     BadWindow - a window in request is not valid
 *     Success
 *
 *****************************************************************************/

static int
444
ProcDbeSwapBuffers(ClientPtr client)
445 446
{
    REQUEST(xDbeSwapBuffersReq);
447 448 449 450 451
    WindowPtr pWin;
    DbeScreenPrivPtr pDbeScreenPriv;
    DbeSwapInfoPtr swapInfo;
    xDbeSwapInfo *dbeSwapInfo;
    int error;
452 453
    unsigned int i, j;
    unsigned int nStuff;
454
    int nStuff_i;       /* DDX API requires int for nStuff */
455 456

    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
457
    nStuff = stuff->n;          /* use local variable for performance. */
458

459
    if (nStuff == 0) {
460
        REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
461
        return Success;
462 463
    }

464
    if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
465
        return BadAlloc;
466
    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
467

468
    /* Get to the swap info appended to the end of the request. */
469
    dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
470

471
    /* Allocate array to record swap information. */
472
    swapInfo = xallocarray(nStuff, sizeof(DbeSwapInfoRec));
473
    if (swapInfo == NULL) {
474
        return BadAlloc;
475 476
    }

477
    for (i = 0; i < nStuff; i++) {
478 479 480
        /* Check all windows to swap. */

        /* Each window must be a valid window - BadWindow. */
481 482 483
        error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
                                DixWriteAccess);
        if (error != Success) {
484
            free(swapInfo);
485
            return error;
486 487 488
        }

        /* Each window must be double-buffered - BadMatch. */
489
        if (DBE_WINDOW_PRIV(pWin) == NULL) {
490
            free(swapInfo);
491
            return BadMatch;
492 493 494
        }

        /* Each window must only be specified once - BadMatch. */
495 496
        for (j = i + 1; j < nStuff; j++) {
            if (dbeSwapInfo[i].window == dbeSwapInfo[j].window) {
497
                free(swapInfo);
498
                return BadMatch;
499
            }
500 501 502
        }

        /* Each swap action must be valid - BadValue. */
503
        if ((dbeSwapInfo[i].swapAction != XdbeUndefined) &&
504
            (dbeSwapInfo[i].swapAction != XdbeBackground) &&
505 506
            (dbeSwapInfo[i].swapAction != XdbeUntouched) &&
            (dbeSwapInfo[i].swapAction != XdbeCopied)) {
507
            free(swapInfo);
508
            return BadValue;
509 510 511
        }

        /* Everything checks out OK.  Fill in the swap info array. */
512 513
        swapInfo[i].pWindow = pWin;
        swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
514

515
    }                           /* for (i = 0; i < nStuff; i++) */
516 517 518 519 520 521 522 523 524 525 526 527 528 529

    /* Call the DDX routine to perform the swap(s).  The DDX routine should
     * scan the swap list (swap info), swap any buffers that it knows how to
     * handle, delete them from the list, and update nStuff to indicate how
     * many windows it did not handle.
     *
     * This scheme allows a range of sophistication in the DDX SwapBuffers()
     * implementation.  Naive implementations could just swap the first buffer
     * in the list, move the last buffer to the front, decrement nStuff, and
     * return.  The next level of sophistication could be to scan the whole
     * list for windows on the same screen.  Up another level, the DDX routine
     * could deal with cross-screen synchronization.
     */

530 531
    nStuff_i = nStuff;
    while (nStuff_i > 0) {
532
        pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
533
        error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff_i, swapInfo);
534
        if (error != Success) {
535
            free(swapInfo);
536
            return error;
537 538
        }
    }
539

540
    free(swapInfo);
541
    return Success;
542

543
}                               /* ProcDbeSwapBuffers() */
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562

/******************************************************************************
 *
 * DBE DIX Procedure: ProcDbeGetVisualInfo
 *
 * Description:
 *
 *     This function is for processing a ProcDbeGetVisualInfo request.
 *     This request returns information about which visuals support
 *     double buffering.
 *
 * Return Values:
 *
 *     BadDrawable - value in screen specifiers is not a valid drawable
 *     Success
 *
 *****************************************************************************/

static int
563
ProcDbeGetVisualInfo(ClientPtr client)
564 565
{
    REQUEST(xDbeGetVisualInfoReq);
566 567 568 569 570 571 572 573 574
    DbeScreenPrivPtr pDbeScreenPriv;
    xDbeGetVisualInfoReply rep;
    Drawable *drawables;
    DrawablePtr *pDrawables = NULL;
    register int i, j, rc;
    register int count;         /* number of visual infos in reply */
    register int length;        /* length of reply */
    ScreenPtr pScreen;
    XdbeScreenVisualInfo *pScrVisInfo;
575 576

    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
577 578 579
    if (stuff->n > UINT32_MAX / sizeof(CARD32))
        return BadLength;
    REQUEST_FIXED_SIZE(xDbeGetVisualInfoReq, stuff->n * sizeof(CARD32));
580

581
    if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
582
        return BadAlloc;
583
    /* Make sure any specified drawables are valid. */
584
    if (stuff->n != 0) {
585
        if (!(pDrawables = xallocarray(stuff->n, sizeof(DrawablePtr)))) {
586
            return BadAlloc;
587 588
        }

589
        drawables = (Drawable *) &stuff[1];
590

591 592 593 594
        for (i = 0; i < stuff->n; i++) {
            rc = dixLookupDrawable(pDrawables + i, drawables[i], client, 0,
                                   DixGetAttrAccess);
            if (rc != Success) {
595
                free(pDrawables);
596
                return rc;
597 598 599 600 601
            }
        }
    }

    count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
602
    if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo)))) {
603
        free(pDrawables);
604

605
        return BadAlloc;
606 607 608 609
    }

    length = 0;

610
    for (i = 0; i < count; i++) {
611
        pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
612
            pDrawables[i]->pScreen;
613 614
        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);

615
        rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
616 617 618
        if (rc != Success)
            goto freeScrVisInfo;

619
        if (!(*pDbeScreenPriv->GetVisualInfo) (pScreen, &pScrVisInfo[i])) {
620
            /* We failed to alloc pScrVisInfo[i].visinfo. */
621
            rc = BadAlloc;
622

623
            /* Free visinfos that we allocated for previous screen infos. */
624
            goto freeScrVisInfo;
625 626 627 628 629 630 631 632 633
        }

        /* Account for n, number of xDbeVisInfo items in list. */
        length += sizeof(CARD32);

        /* Account for n xDbeVisInfo items */
        length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
    }

634 635 636 637 638 639
    rep = (xDbeGetVisualInfoReply) {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = bytes_to_int32(length),
        .m = count
    };
640

641
    if (client->swapped) {
642 643 644
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.m);
645 646 647
    }

    /* Send off reply. */
648
    WriteToClient(client, sizeof(xDbeGetVisualInfoReply), &rep);
649

650 651
    for (i = 0; i < count; i++) {
        CARD32 data32;
652 653 654 655

        /* For each screen in the reply, send off the visual info */

        /* Send off number of visuals. */
656
        data32 = (CARD32) pScrVisInfo[i].count;
657

658
        if (client->swapped) {
659
            swapl(&data32);
660 661
        }

662
        WriteToClient(client, sizeof(CARD32), &data32);
663 664

        /* Now send off visual info items. */
665 666
        for (j = 0; j < pScrVisInfo[i].count; j++) {
            xDbeVisInfo visInfo;
667 668 669 670 671 672

            /* Copy the data in the client data structure to a protocol
             * data structure.  We will send data to the client from the
             * protocol data structure.
             */

673 674
            visInfo.visualID = (CARD32) pScrVisInfo[i].visinfo[j].visual;
            visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth;
675 676
            visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;

677
            if (client->swapped) {
678
                swapl(&visInfo.visualID);
679 680 681 682 683 684 685

                /* We do not need to swap depth and perfLevel since they are
                 * already 1 byte quantities.
                 */
            }

            /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
686
            WriteToClient(client, 2 * sizeof(CARD32), &visInfo.visualID);
687 688 689
        }
    }

690 691
    rc = Success;

692
 freeScrVisInfo:
693
    /* Clean up memory. */
694
    for (i = 0; i < count; i++) {
695
        free(pScrVisInfo[i].visinfo);
696
    }
697
    free(pScrVisInfo);
698

699
    free(pDrawables);
700

701
    return rc;
702

703
}                               /* ProcDbeGetVisualInfo() */
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720

/******************************************************************************
 *
 * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
 *
 * Description:
 *
 *     This function is for processing a ProcDbeGetbackBufferAttributes
 *     request.  This request returns information about a back buffer.
 *
 * Return Values:
 *
 *     Success
 *
 *****************************************************************************/

static int
721
ProcDbeGetBackBufferAttributes(ClientPtr client)
722 723
{
    REQUEST(xDbeGetBackBufferAttributesReq);
724 725 726 727 728
    xDbeGetBackBufferAttributesReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0
    };
729 730
    DbeWindowPrivPtr pDbeWindowPriv;
    int rc;
731 732 733

    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);

734
    rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer,
735 736 737
                                 dbeWindowPrivResType, client,
                                 DixGetAttrAccess);
    if (rc == Success) {
738
        rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
739
    }
740
    else {
741
        rep.attributes = None;
742
    }
743 744

    if (client->swapped) {
745 746 747
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.attributes);
748 749
    }

750
    WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply), &rep);
751
    return Success;
752

753
}                               /* ProcDbeGetbackBufferAttributes() */
754 755 756 757 758 759 760 761 762 763 764 765

/******************************************************************************
 *
 * DBE DIX Procedure: ProcDbeDispatch
 *
 * Description:
 *
 *     This function dispatches DBE requests.
 *
 *****************************************************************************/

static int
766
ProcDbeDispatch(ClientPtr client)
767 768 769
{
    REQUEST(xReq);

770 771 772
    switch (stuff->data) {
    case X_DbeGetVersion:
        return (ProcDbeGetVersion(client));
773

774 775
    case X_DbeAllocateBackBufferName:
        return (ProcDbeAllocateBackBufferName(client));
776

777 778
    case X_DbeDeallocateBackBufferName:
        return (ProcDbeDeallocateBackBufferName(client));
779

780 781
    case X_DbeSwapBuffers:
        return (ProcDbeSwapBuffers(client));
782

783
    case X_DbeBeginIdiom:
784
        return Success;
785

786 787
    case X_DbeEndIdiom:
        return Success;
788

789 790
    case X_DbeGetVisualInfo:
        return (ProcDbeGetVisualInfo(client));
791

792 793
    case X_DbeGetBackBufferAttributes:
        return (ProcDbeGetBackBufferAttributes(client));
794

795 796
    default:
        return BadRequest;
797 798
    }

799
}                               /* ProcDbeDispatch() */
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816

/******************************************************************************
 *
 * DBE DIX Procedure: SProcDbeGetVersion
 *
 * Description:
 *
 *     This function is for processing a DbeGetVersion request on a swapped
 *     server.  This request returns the major and minor version numbers of
 *     this extension.
 *
 * Return Values:
 *
 *     Success
 *
 *****************************************************************************/

817
static int _X_COLD
818
SProcDbeGetVersion(ClientPtr client)
819 820 821
{
    REQUEST(xDbeGetVersionReq);

822
    swaps(&stuff->length);
823
    return (ProcDbeGetVersion(client));
824

825
}                               /* SProcDbeGetVersion() */
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842

/******************************************************************************
 *
 * DBE DIX Procedure: SProcDbeAllocateBackBufferName
 *
 * Description:
 *
 *     This function is for processing a DbeAllocateBackBufferName request on
 *     a swapped server.  This request allocates a drawable ID used to refer
 *     to the back buffer of a window.
 *
 * Return Values:
 *
 *     BadAlloc    - server can not allocate resources
 *     BadIDChoice - id is out of range for client; id is already in use
 *     BadMatch    - window is not an InputOutput window;
 *                   visual of window is not on list returned by
843
 *                   DBEGetVisualInfo;
844 845 846 847 848 849
 *     BadValue    - invalid swap action is specified
 *     BadWindow   - window is not a valid window
 *     Success
 *
 *****************************************************************************/

850
static int _X_COLD
851
SProcDbeAllocateBackBufferName(ClientPtr client)
852 853 854
{
    REQUEST(xDbeAllocateBackBufferNameReq);

855
    swaps(&stuff->length);
856 857
    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);

858 859
    swapl(&stuff->window);
    swapl(&stuff->buffer);
860 861
    /* stuff->swapAction is a byte.  We do not need to swap this field. */

862
    return (ProcDbeAllocateBackBufferName(client));
863

864
}                               /* SProcDbeAllocateBackBufferName() */
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882

/******************************************************************************
 *
 * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
 *
 * Description:
 *
 *     This function is for processing a DbeDeallocateBackBufferName request
 *     on a swapped server.  This request frees a drawable ID that was
 *     obtained by a DbeAllocateBackBufferName request.
 *
 * Return Values:
 *
 *     BadBuffer - buffer to deallocate is not associated with a window
 *     Success
 *
 *****************************************************************************/

883
static int _X_COLD
884
SProcDbeDeallocateBackBufferName(ClientPtr client)
885
{
886
    REQUEST(xDbeDeallocateBackBufferNameReq);
887

888
    swaps(&stuff->length);
889 890
    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);

891
    swapl(&stuff->buffer);
892

893
    return (ProcDbeDeallocateBackBufferName(client));
894

895
}                               /* SProcDbeDeallocateBackBufferName() */
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917

/******************************************************************************
 *
 * DBE DIX Procedure: SProcDbeSwapBuffers
 *
 * Description:
 *
 *     This function is for processing a DbeSwapBuffers request on a swapped
 *     server.  This request swaps the buffers for all windows listed,
 *     applying the appropriate swap action for each window.
 *
 * Return Values:
 *
 *     BadMatch  - a window in request is not double-buffered; a window in
 *                 request is listed more than once; all windows in request do
 *                 not have the same root
 *     BadValue  - invalid swap action is specified
 *     BadWindow - a window in request is not valid
 *     Success
 *
 *****************************************************************************/

918
static int _X_COLD
919
SProcDbeSwapBuffers(ClientPtr client)
920 921
{
    REQUEST(xDbeSwapBuffersReq);
922
    unsigned int i;
923
    xDbeSwapInfo *pSwapInfo;
924

925
    swaps(&stuff->length);
926 927
    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);

928
    swapl(&stuff->n);
929
    if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
930
        return BadLength;
931
    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
932

933 934
    if (stuff->n != 0) {
        pSwapInfo = (xDbeSwapInfo *) stuff + 1;
935 936 937 938 939

        /* The swap info following the fix part of this request is a window(32)
         * followed by a 1 byte swap action and then 3 pad bytes.  We only need
         * to swap the window information.
         */
940
        for (i = 0; i < stuff->n; i++) {
941
            swapl(&pSwapInfo->window);
942 943 944
        }
    }

945
    return (ProcDbeSwapBuffers(client));
946

947
}                               /* SProcDbeSwapBuffers() */
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965

/******************************************************************************
 *
 * DBE DIX Procedure: SProcDbeGetVisualInfo
 *
 * Description:
 *
 *     This function is for processing a ProcDbeGetVisualInfo request on a
 *     swapped server.  This request returns information about which visuals
 *     support double buffering.
 *
 * Return Values:
 *
 *     BadDrawable - value in screen specifiers is not a valid drawable
 *     Success
 *
 *****************************************************************************/

966
static int _X_COLD
967
SProcDbeGetVisualInfo(ClientPtr client)
968 969 970
{
    REQUEST(xDbeGetVisualInfoReq);

971
    swaps(&stuff->length);
972 973
    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);

974
    swapl(&stuff->n);
975 976
    SwapRestL(stuff);

977
    return (ProcDbeGetVisualInfo(client));
978

979
}                               /* SProcDbeGetVisualInfo() */
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996

/******************************************************************************
 *
 * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
 *
 * Description:
 *
 *     This function is for processing a ProcDbeGetbackBufferAttributes
 *     request on a swapped server.  This request returns information about a
 *     back buffer.
 *
 * Return Values:
 *
 *     Success
 *
 *****************************************************************************/

997
static int _X_COLD
998
SProcDbeGetBackBufferAttributes(ClientPtr client)
999
{
1000
    REQUEST(xDbeGetBackBufferAttributesReq);
1001

1002
    swaps(&stuff->length);
1003 1004
    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);

1005
    swapl(&stuff->buffer);
1006

1007
    return (ProcDbeGetBackBufferAttributes(client));
1008

1009
}                               /* SProcDbeGetBackBufferAttributes() */
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020

/******************************************************************************
 *
 * DBE DIX Procedure: SProcDbeDispatch
 *
 * Description:
 *
 *     This function dispatches DBE requests on a swapped server.
 *
 *****************************************************************************/

1021
static int _X_COLD
1022
SProcDbeDispatch(ClientPtr client)
1023 1024 1025
{
    REQUEST(xReq);

1026 1027 1028
    switch (stuff->data) {
    case X_DbeGetVersion:
        return (SProcDbeGetVersion(client));
1029

1030 1031
    case X_DbeAllocateBackBufferName:
        return (SProcDbeAllocateBackBufferName(client));
1032

1033 1034
    case X_DbeDeallocateBackBufferName:
        return (SProcDbeDeallocateBackBufferName(client));
1035

1036 1037
    case X_DbeSwapBuffers:
        return (SProcDbeSwapBuffers(client));
1038

1039
    case X_DbeBeginIdiom:
1040
        return Success;
1041

1042 1043
    case X_DbeEndIdiom:
        return Success;
1044

1045 1046
    case X_DbeGetVisualInfo:
        return (SProcDbeGetVisualInfo(client));
1047

1048 1049
    case X_DbeGetBackBufferAttributes:
        return (SProcDbeGetBackBufferAttributes(client));
1050

1051 1052
    default:
        return BadRequest;
1053 1054
    }

1055
}                               /* SProcDbeDispatch() */
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068

/******************************************************************************
 *
 * DBE DIX Procedure: DbeSetupBackgroundPainter
 *
 * Description:
 *
 *     This function sets up pGC to clear pixmaps.
 *
 * Return Values:
 *
 *     TRUE  - setup was successful
 *     FALSE - the window's background state is NONE
1069
 *
1070 1071 1072
 *****************************************************************************/

static Bool
1073
DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
1074
{
1075 1076 1077 1078 1079
    ChangeGCVal gcvalues[4];
    int ts_x_origin, ts_y_origin;
    PixUnion background;
    int backgroundState;
    Mask gcmask;
1080 1081 1082 1083 1084 1085 1086

    /* First take care of any ParentRelative stuff by altering the
     * tile/stipple origin to match the coordinates of the upper-left
     * corner of the first ancestor without a ParentRelative background.
     * This coordinate is, of course, negative.
     */
    ts_x_origin = ts_y_origin = 0;
1087
    while (pWin->backgroundState == ParentRelative) {
1088 1089 1090 1091 1092 1093
        ts_x_origin -= pWin->origin.x;
        ts_y_origin -= pWin->origin.y;

        pWin = pWin->parent;
    }
    backgroundState = pWin->backgroundState;
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
    background = pWin->background;

    switch (backgroundState) {
    case BackgroundPixel:
        gcvalues[0].val = background.pixel;
        gcvalues[1].val = FillSolid;
        gcmask = GCForeground | GCFillStyle;
        break;

    case BackgroundPixmap:
        gcvalues[0].val = FillTiled;
        gcvalues[1].ptr = background.pixmap;
        gcvalues[2].val = ts_x_origin;
        gcvalues[3].val = ts_y_origin;
        gcmask = GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
        break;

    default:
        /* pWin->backgroundState == None */
        return FALSE;
1114 1115
    }

1116
    return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
1117
}                               /* DbeSetupBackgroundPainter() */
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135

/******************************************************************************
 *
 * DBE DIX Procedure: DbeDrawableDelete
 *
 * Description:
 *
 *     This is the resource delete function for dbeDrawableResType.
 *     It is registered when the drawable resource type is created in
 *     DbeExtensionInit().
 *
 *     To make resource deletion simple, we do not do anything in this function
 *     and leave all resource deleteion to DbeWindowPrivDelete(), which will
 *     eventually be called or already has been called.  Deletion functions are
 *     not guaranteed to be called in any particular order.
 *
 *****************************************************************************/
static int
1136
DbeDrawableDelete(void *pDrawable, XID id)
1137
{
1138
    return Success;
1139

1140
}                               /* DbeDrawableDelete() */
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153

/******************************************************************************
 *
 * DBE DIX Procedure: DbeWindowPrivDelete
 *
 * Description:
 *
 *     This is the resource delete function for dbeWindowPrivResType.
 *     It is registered when the drawable resource type is created in
 *     DbeExtensionInit().
 *
 *****************************************************************************/
static int
1154
DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
1155
{
1156 1157 1158
    DbeScreenPrivPtr pDbeScreenPriv;
    DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr) pDbeWinPriv;
    int i;
1159 1160 1161 1162 1163 1164 1165 1166 1167

    /*
     **************************************************************************
     ** Remove the buffer ID from the ID array.
     **************************************************************************
     */

    /* Find the ID in the ID array. */
    i = 0;
1168
    while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) {
1169 1170 1171
        i++;
    }

1172
    if (i == pDbeWindowPriv->nBufferIDs) {
1173
        /* We did not find the ID in the array.  We should never get here. */
1174
        return BadValue;
1175 1176 1177 1178
    }

    /* Remove the ID from the array. */

1179
    if (i < (pDbeWindowPriv->nBufferIDs - 1)) {
1180
        /* Compress the buffer ID array, overwriting the ID in the process. */
1181 1182
        memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i + 1],
                (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
1183
    }
1184
    else {
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
        /* We are removing the last ID in the array, in which case, the
         * assignement below is all that we need to do.
         */
    }
    pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;

    pDbeWindowPriv->nBufferIDs--;

    /* If an extended array was allocated, then check to see if the remaining
     * buffer IDs will fit in the static array.
     */

1197 1198
    if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) &&
        (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) {
1199 1200 1201 1202 1203
        /* Copy the IDs back into the static array. */
        memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
               DBE_INIT_MAX_IDS * sizeof(XID));

        /* Free the extended array; use the static array. */
1204
        free(pDbeWindowPriv->IDs);
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
    }

    /*
     **************************************************************************
     ** Perform DDX level tasks.
     **************************************************************************
     */

1215 1216 1217
    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV((DbeWindowPrivPtr)
                                                      pDbeWindowPriv);
    (*pDbeScreenPriv->WinPrivDelete) ((DbeWindowPrivPtr) pDbeWindowPriv, id);
1218 1219 1220 1221 1222 1223 1224 1225

    /*
     **************************************************************************
     ** Perform miscellaneous tasks if this is the last buffer associated
     ** with the window.
     **************************************************************************
     */

1226
    if (pDbeWindowPriv->nBufferIDs == 0) {
1227
        /* Reset the DBE window priv pointer. */
1228 1229
        dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
                      NULL);
1230 1231

        /* We are done with the window priv. */
1232
        free(pDbeWindowPriv);
1233 1234
    }

1235
    return Success;
1236

1237
}                               /* DbeWindowPrivDelete() */
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250

/******************************************************************************
 *
 * DBE DIX Procedure: DbeResetProc
 *
 * Description:
 *
 *     This routine is called at the end of every server generation.
 *     It deallocates any memory reserved for the extension and performs any
 *     other tasks related to shutting down the extension.
 *
 *****************************************************************************/
static void
1251
DbeResetProc(ExtensionEntry * extEntry)
1252
{
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262
    int i;
    ScreenPtr pScreen;
    DbeScreenPrivPtr pDbeScreenPriv;

    for (i = 0; i < screenInfo.numScreens; i++) {
        pScreen = screenInfo.screens[i];
        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);

        if (pDbeScreenPriv) {
            /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */
1263
            pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1264
            pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
1265 1266
            free(pDbeScreenPriv);
        }
1267
    }
1268
}                               /* DbeResetProc() */
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282

/******************************************************************************
 *
 * DBE DIX Procedure: DbeDestroyWindow
 *
 * Description:
 *
 *     This is the wrapper for pScreen->DestroyWindow.
 *     This function frees buffer resources for a window before it is
 *     destroyed.
 *
 *****************************************************************************/

static Bool
1283
DbeDestroyWindow(WindowPtr pWin)
1284
{
1285 1286 1287 1288
    DbeScreenPrivPtr pDbeScreenPriv;
    DbeWindowPrivPtr pDbeWindowPriv;
    ScreenPtr pScreen;
    Bool ret;
1289 1290 1291 1292 1293 1294 1295

    /*
     **************************************************************************
     ** 1. Unwrap the member routine.
     **************************************************************************
     */

1296 1297
    pScreen = pWin->drawable.pScreen;
    pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308
    pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;

    /*
     **************************************************************************
     ** 2. Do any work necessary before the member routine is called.
     **
     **    Call the window priv delete function for all buffer IDs associated
     **    with this window.
     **************************************************************************
     */

1309 1310
    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) {
        while (pDbeWindowPriv) {
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
            /* *DbeWinPrivDelete() will free the window private and set it to
             * NULL if there are no more buffer IDs associated with this
             * window.
             */
            FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
            pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
        }
    }

    /*
     **************************************************************************
     ** 3. Call the member routine, saving its result if necessary.
     **************************************************************************
     */

1326
    ret = (*pScreen->DestroyWindow) (pWin);
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345

    /*
     **************************************************************************
     ** 4. Rewrap the member routine, restoring the wrapper value first in case
     **    the wrapper (or something that it wrapped) change this value.
     **************************************************************************
     */

    pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
    pScreen->DestroyWindow = DbeDestroyWindow;

    /*
     **************************************************************************
     ** 5. Do any work necessary after the member routine has been called.
     **
     **    In this case we do not need to do anything.
     **************************************************************************
     */

1346
    return ret;
1347

1348
}                               /* DbeDestroyWindow() */
1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359

/******************************************************************************
 *
 * DBE DIX Procedure: DbeExtensionInit
 *
 * Description:
 *
 *     Called from InitExtensions in main()
 *
 *****************************************************************************/

1360
void
1361
DbeExtensionInit(void)
1362
{
1363 1364 1365 1366 1367 1368
    ExtensionEntry *extEntry;
    register int i, j;
    ScreenPtr pScreen = NULL;
    DbeScreenPrivPtr pDbeScreenPriv;
    int nStubbedScreens = 0;
    Bool ddxInitSuccess;
1369

1370
#ifdef PANORAMIX
1371 1372
    if (!noPanoramiXExtension)
        return;
1373
#endif
1374 1375 1376

    /* Create the resource types. */
    dbeDrawableResType =
1377
        CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
1378
    if (!dbeDrawableResType)
1379
        return;
1380 1381
    dbeDrawableResType |= RC_DRAWABLE;

1382
    dbeWindowPrivResType =
1383
        CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
1384
    if (!dbeWindowPrivResType)
1385
        return;
1386

1387
    if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0))
1388
        return;
1389