1706f2543Smrg/******************************************************************************
2706f2543Smrg *
3706f2543Smrg * Copyright (c) 1994, 1995  Hewlett-Packard Company
4706f2543Smrg *
5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining
6706f2543Smrg * a copy of this software and associated documentation files (the
7706f2543Smrg * "Software"), to deal in the Software without restriction, including
8706f2543Smrg * without limitation the rights to use, copy, modify, merge, publish,
9706f2543Smrg * distribute, sublicense, and/or sell copies of the Software, and to
10706f2543Smrg * permit persons to whom the Software is furnished to do so, subject to
11706f2543Smrg * the following conditions:
12706f2543Smrg *
13706f2543Smrg * The above copyright notice and this permission notice shall be included
14706f2543Smrg * in all copies or substantial portions of the Software.
15706f2543Smrg *
16706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17706f2543Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19706f2543Smrg * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
20706f2543Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21706f2543Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22706f2543Smrg * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23706f2543Smrg *
24706f2543Smrg * Except as contained in this notice, the name of the Hewlett-Packard
25706f2543Smrg * Company shall not be used in advertising or otherwise to promote the
26706f2543Smrg * sale, use or other dealings in this Software without prior written
27706f2543Smrg * authorization from the Hewlett-Packard Company.
28706f2543Smrg *
29706f2543Smrg *     DIX DBE code
30706f2543Smrg *
31706f2543Smrg *****************************************************************************/
32706f2543Smrg
33706f2543Smrg
34706f2543Smrg/* INCLUDES */
35706f2543Smrg
36706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
37706f2543Smrg#include <dix-config.h>
38706f2543Smrg#endif
39706f2543Smrg
40706f2543Smrg#include <string.h>
41706f2543Smrg#if HAVE_STDINT_H
42706f2543Smrg#include <stdint.h>
43706f2543Smrg#elif !defined(UINT32_MAX)
44706f2543Smrg#define UINT32_MAX 0xffffffffU
45706f2543Smrg#endif
46706f2543Smrg
47706f2543Smrg#include <X11/X.h>
48706f2543Smrg#include <X11/Xproto.h>
49706f2543Smrg#include "scrnintstr.h"
50706f2543Smrg#include "extnsionst.h"
51706f2543Smrg#include "gcstruct.h"
52706f2543Smrg#include "dixstruct.h"
53706f2543Smrg#define NEED_DBE_PROTOCOL
54706f2543Smrg#include "dbestruct.h"
55706f2543Smrg#include "midbe.h"
56706f2543Smrg#include "xace.h"
57706f2543Smrg
58706f2543Smrg/* GLOBALS */
59706f2543Smrg
60706f2543Smrg/* These are globals for use by DDX */
61706f2543SmrgDevPrivateKeyRec dbeScreenPrivKeyRec;
62706f2543SmrgDevPrivateKeyRec dbeWindowPrivKeyRec;
63706f2543Smrg
64706f2543Smrg/* These are globals for use by DDX */
65706f2543SmrgRESTYPE	dbeDrawableResType;
66706f2543SmrgRESTYPE	dbeWindowPrivResType;
67706f2543Smrg
68706f2543Smrg/* Used to generate DBE's BadBuffer error. */
69706f2543Smrgstatic int	dbeErrorBase;
70706f2543Smrg
71706f2543Smrg/******************************************************************************
72706f2543Smrg *
73706f2543Smrg * DBE DIX Procedure: DbeStubScreen
74706f2543Smrg *
75706f2543Smrg * Description:
76706f2543Smrg *
77706f2543Smrg *     This is function stubs the function pointers in the given DBE screen
78706f2543Smrg *     private and increments the number of stubbed screens.
79706f2543Smrg *
80706f2543Smrg *****************************************************************************/
81706f2543Smrg
82706f2543Smrgstatic void
83706f2543SmrgDbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
84706f2543Smrg{
85706f2543Smrg    /* Stub DIX. */
86706f2543Smrg    pDbeScreenPriv->SetupBackgroundPainter = NULL;
87706f2543Smrg
88706f2543Smrg    /* Do not unwrap PositionWindow nor DestroyWindow.  If the DDX
89706f2543Smrg     * initialization function failed, we assume that it did not wrap
90706f2543Smrg     * PositionWindow.  Also, DestroyWindow is only wrapped if the DDX
91706f2543Smrg     * initialization function succeeded.
92706f2543Smrg     */
93706f2543Smrg
94706f2543Smrg    /* Stub DDX. */
95706f2543Smrg    pDbeScreenPriv->GetVisualInfo       = NULL;
96706f2543Smrg    pDbeScreenPriv->AllocBackBufferName = NULL;
97706f2543Smrg    pDbeScreenPriv->SwapBuffers         = NULL;
98706f2543Smrg    pDbeScreenPriv->BeginIdiom          = NULL;
99706f2543Smrg    pDbeScreenPriv->EndIdiom            = NULL;
100706f2543Smrg    pDbeScreenPriv->WinPrivDelete       = NULL;
101706f2543Smrg    pDbeScreenPriv->ResetProc           = NULL;
102706f2543Smrg
103706f2543Smrg    (*nStubbedScreens)++;
104706f2543Smrg
105706f2543Smrg} /* DbeStubScreen() */
106706f2543Smrg
107706f2543Smrg
108706f2543Smrg
109706f2543Smrg/******************************************************************************
110706f2543Smrg *
111706f2543Smrg * DBE DIX Procedure: ProcDbeGetVersion
112706f2543Smrg *
113706f2543Smrg * Description:
114706f2543Smrg *
115706f2543Smrg *     This function is for processing a DbeGetVersion request.
116706f2543Smrg *     This request returns the major and minor version numbers of this
117706f2543Smrg *     extension.
118706f2543Smrg *
119706f2543Smrg * Return Values:
120706f2543Smrg *
121706f2543Smrg *     Success
122706f2543Smrg *
123706f2543Smrg *****************************************************************************/
124706f2543Smrg
125706f2543Smrgstatic int
126706f2543SmrgProcDbeGetVersion(ClientPtr client)
127706f2543Smrg{
128706f2543Smrg    /* REQUEST(xDbeGetVersionReq); */
129706f2543Smrg    xDbeGetVersionReply	rep;
130706f2543Smrg    register int	n;
131706f2543Smrg
132706f2543Smrg
133706f2543Smrg    REQUEST_SIZE_MATCH(xDbeGetVersionReq);
134706f2543Smrg
135706f2543Smrg    rep.type           = X_Reply;
136706f2543Smrg    rep.length         = 0;
137706f2543Smrg    rep.sequenceNumber = client->sequence;
138706f2543Smrg    rep.majorVersion   = DBE_MAJOR_VERSION;
139706f2543Smrg    rep.minorVersion   = DBE_MINOR_VERSION;
140706f2543Smrg
141706f2543Smrg    if (client->swapped)
142706f2543Smrg    {
143706f2543Smrg        swaps(&rep.sequenceNumber, n);
144706f2543Smrg    }
145706f2543Smrg
146706f2543Smrg    WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep);
147706f2543Smrg
148706f2543Smrg    return Success;
149706f2543Smrg
150706f2543Smrg} /* ProcDbeGetVersion() */
151706f2543Smrg
152706f2543Smrg
153706f2543Smrg/******************************************************************************
154706f2543Smrg *
155706f2543Smrg * DBE DIX Procedure: ProcDbeAllocateBackBufferName
156706f2543Smrg *
157706f2543Smrg * Description:
158706f2543Smrg *
159706f2543Smrg *     This function is for processing a DbeAllocateBackBufferName request.
160706f2543Smrg *     This request allocates a drawable ID used to refer to the back buffer
161706f2543Smrg *     of a window.
162706f2543Smrg *
163706f2543Smrg * Return Values:
164706f2543Smrg *
165706f2543Smrg *     BadAlloc    - server can not allocate resources
166706f2543Smrg *     BadIDChoice - id is out of range for client; id is already in use
167706f2543Smrg *     BadMatch    - window is not an InputOutput window;
168706f2543Smrg *                   visual of window is not on list returned by
169706f2543Smrg *                   DBEGetVisualInfo;
170706f2543Smrg *     BadValue    - invalid swap action is specified
171706f2543Smrg *     BadWindow   - window is not a valid window
172706f2543Smrg *     Success
173706f2543Smrg *
174706f2543Smrg *****************************************************************************/
175706f2543Smrg
176706f2543Smrgstatic int
177706f2543SmrgProcDbeAllocateBackBufferName(ClientPtr client)
178706f2543Smrg{
179706f2543Smrg    REQUEST(xDbeAllocateBackBufferNameReq);
180706f2543Smrg    WindowPtr			pWin;
181706f2543Smrg    DbeScreenPrivPtr		pDbeScreenPriv;
182706f2543Smrg    DbeWindowPrivPtr		pDbeWindowPriv;
183706f2543Smrg    XdbeScreenVisualInfo	scrVisInfo;
184706f2543Smrg    register int		i;
185706f2543Smrg    Bool			visualMatched = FALSE;
186706f2543Smrg    xDbeSwapAction		swapAction;
187706f2543Smrg    VisualID			visual;
188706f2543Smrg    int				status;
189706f2543Smrg    int				add_index;
190706f2543Smrg
191706f2543Smrg
192706f2543Smrg    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
193706f2543Smrg
194706f2543Smrg    /* The window must be valid. */
195706f2543Smrg    status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
196706f2543Smrg    if (status != Success)
197706f2543Smrg	return status;
198706f2543Smrg
199706f2543Smrg    /* The window must be InputOutput. */
200706f2543Smrg    if (pWin->drawable.class != InputOutput)
201706f2543Smrg    {
202706f2543Smrg	return BadMatch;
203706f2543Smrg    }
204706f2543Smrg
205706f2543Smrg    /* The swap action must be valid. */
206706f2543Smrg    swapAction = stuff->swapAction;	/* use local var for performance. */
207706f2543Smrg    if ((swapAction != XdbeUndefined ) &&
208706f2543Smrg        (swapAction != XdbeBackground) &&
209706f2543Smrg        (swapAction != XdbeUntouched ) &&
210706f2543Smrg        (swapAction != XdbeCopied    ))
211706f2543Smrg    {
212706f2543Smrg        return BadValue;
213706f2543Smrg    }
214706f2543Smrg
215706f2543Smrg    /* The id must be in range and not already in use. */
216706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->buffer, client);
217706f2543Smrg
218706f2543Smrg    /* The visual of the window must be in the list returned by
219706f2543Smrg     * GetVisualInfo.
220706f2543Smrg     */
221706f2543Smrg    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
222706f2543Smrg    if (!pDbeScreenPriv->GetVisualInfo)
223706f2543Smrg	return BadMatch; /* screen doesn't support double buffering */
224706f2543Smrg
225706f2543Smrg    if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
226706f2543Smrg    {
227706f2543Smrg        /* GetVisualInfo() failed to allocate visual info data. */
228706f2543Smrg        return BadAlloc;
229706f2543Smrg    }
230706f2543Smrg
231706f2543Smrg    /* See if the window's visual is on the list. */
232706f2543Smrg    visual = wVisual(pWin);
233706f2543Smrg    for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++)
234706f2543Smrg    {
235706f2543Smrg        if (scrVisInfo.visinfo[i].visual == visual)
236706f2543Smrg	{
237706f2543Smrg	    visualMatched = TRUE;
238706f2543Smrg	}
239706f2543Smrg    }
240706f2543Smrg
241706f2543Smrg    /* Free what was allocated by the GetVisualInfo() call above. */
242706f2543Smrg    free(scrVisInfo.visinfo);
243706f2543Smrg
244706f2543Smrg    if (!visualMatched)
245706f2543Smrg    {
246706f2543Smrg	return BadMatch;
247706f2543Smrg    }
248706f2543Smrg
249706f2543Smrg    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
250706f2543Smrg    {
251706f2543Smrg        /* There is no buffer associated with the window.
252706f2543Smrg         * Allocate a window priv.
253706f2543Smrg         */
254706f2543Smrg
255706f2543Smrg        pDbeWindowPriv = dixAllocateObjectWithPrivates(DbeWindowPrivRec, PRIVATE_DBE_WINDOW);
256706f2543Smrg	if (!pDbeWindowPriv)
257706f2543Smrg            return BadAlloc;
258706f2543Smrg
259706f2543Smrg        /* Fill out window priv information. */
260706f2543Smrg        pDbeWindowPriv->pWindow      = pWin;
261706f2543Smrg        pDbeWindowPriv->width        = pWin->drawable.width;
262706f2543Smrg        pDbeWindowPriv->height       = pWin->drawable.height;
263706f2543Smrg        pDbeWindowPriv->x            = pWin->drawable.x;
264706f2543Smrg        pDbeWindowPriv->y            = pWin->drawable.y;
265706f2543Smrg        pDbeWindowPriv->nBufferIDs   = 0;
266706f2543Smrg
267706f2543Smrg        /* Set the buffer ID array pointer to the initial (static) array). */
268706f2543Smrg        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
269706f2543Smrg
270706f2543Smrg        /* Initialize the buffer ID list. */
271706f2543Smrg        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
272706f2543Smrg        pDbeWindowPriv->IDs[0] = stuff->buffer;
273706f2543Smrg
274706f2543Smrg        add_index = 0;
275706f2543Smrg        for (i = 0; i < DBE_INIT_MAX_IDS; i++)
276706f2543Smrg        {
277706f2543Smrg            pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
278706f2543Smrg        }
279706f2543Smrg
280706f2543Smrg        /* Actually connect the window priv to the window. */
281706f2543Smrg        dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
282706f2543Smrg
283706f2543Smrg    } /* if -- There is no buffer associated with the window. */
284706f2543Smrg
285706f2543Smrg    else
286706f2543Smrg    {
287706f2543Smrg        /* A buffer is already associated with the window.
288706f2543Smrg         * Add the new buffer ID to the array, reallocating the array memory
289706f2543Smrg         * if necessary.
290706f2543Smrg         */
291706f2543Smrg
292706f2543Smrg        /* Determine if there is a free element in the ID array. */
293706f2543Smrg        for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++)
294706f2543Smrg        {
295706f2543Smrg            if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT)
296706f2543Smrg            {
297706f2543Smrg                /* There is still room in the ID array. */
298706f2543Smrg                break;
299706f2543Smrg            }
300706f2543Smrg        }
301706f2543Smrg
302706f2543Smrg        if (i == pDbeWindowPriv->maxAvailableIDs)
303706f2543Smrg        {
304706f2543Smrg            /* No more room in the ID array -- reallocate another array. */
305706f2543Smrg            XID	*pIDs;
306706f2543Smrg
307706f2543Smrg            /* Setup an array pointer for the realloc operation below. */
308706f2543Smrg            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
309706f2543Smrg            {
310706f2543Smrg                /* We will malloc a new array. */
311706f2543Smrg                pIDs = NULL;
312706f2543Smrg            }
313706f2543Smrg            else
314706f2543Smrg            {
315706f2543Smrg                /* We will realloc a new array. */
316706f2543Smrg                pIDs = pDbeWindowPriv->IDs;
317706f2543Smrg            }
318706f2543Smrg
319706f2543Smrg            /* malloc/realloc a new array and initialize all elements to 0. */
320706f2543Smrg            pDbeWindowPriv->IDs = (XID *)realloc(pIDs,
321706f2543Smrg                (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID));
322706f2543Smrg            if (!pDbeWindowPriv->IDs)
323706f2543Smrg            {
324706f2543Smrg                return BadAlloc;
325706f2543Smrg            }
326706f2543Smrg            memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
327706f2543Smrg                   (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
328706f2543Smrg                    pDbeWindowPriv->nBufferIDs) * sizeof(XID));
329706f2543Smrg
330706f2543Smrg            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
331706f2543Smrg            {
332706f2543Smrg                /* We just went from using the initial (static) array to a
333706f2543Smrg                 * newly allocated array.  Copy the IDs from the initial array
334706f2543Smrg                 * to the new array.
335706f2543Smrg                 */
336706f2543Smrg                memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
337706f2543Smrg                       DBE_INIT_MAX_IDS * sizeof(XID));
338706f2543Smrg            }
339706f2543Smrg
340706f2543Smrg            pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
341706f2543Smrg        }
342706f2543Smrg
343706f2543Smrg	add_index = i;
344706f2543Smrg
345706f2543Smrg    } /* else -- A buffer is already associated with the window. */
346706f2543Smrg
347706f2543Smrg
348706f2543Smrg    /* Call the DDX routine to allocate the back buffer. */
349706f2543Smrg    status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
350706f2543Smrg                                                    stuff->swapAction);
351706f2543Smrg
352706f2543Smrg    if (status == Success)
353706f2543Smrg    {
354706f2543Smrg	pDbeWindowPriv->IDs[add_index] = stuff->buffer;
355706f2543Smrg        if (!AddResource(stuff->buffer, dbeWindowPrivResType,
356706f2543Smrg                         (pointer)pDbeWindowPriv))
357706f2543Smrg	{
358706f2543Smrg            pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
359706f2543Smrg
360706f2543Smrg            if (pDbeWindowPriv->nBufferIDs == 0) {
361706f2543Smrg                status = BadAlloc;
362706f2543Smrg                goto out_free;
363706f2543Smrg            }
364706f2543Smrg        }
365706f2543Smrg    } else {
366706f2543Smrg        /* The DDX buffer allocation routine failed for the first buffer of
367706f2543Smrg         * this window.
368706f2543Smrg         */
369706f2543Smrg        if (pDbeWindowPriv->nBufferIDs == 0) {
370706f2543Smrg            goto out_free;
371706f2543Smrg        }
372706f2543Smrg    }
373706f2543Smrg
374706f2543Smrg    /* Increment the number of buffers (XIDs) associated with this window. */
375706f2543Smrg    pDbeWindowPriv->nBufferIDs++;
376706f2543Smrg
377706f2543Smrg    /* Set swap action on all calls. */
378706f2543Smrg    pDbeWindowPriv->swapAction = stuff->swapAction;
379706f2543Smrg
380706f2543Smrg    return status;
381706f2543Smrg
382706f2543Smrgout_free:
383706f2543Smrg    dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
384706f2543Smrg    free(pDbeWindowPriv);
385706f2543Smrg    return status;
386706f2543Smrg
387706f2543Smrg} /* ProcDbeAllocateBackBufferName() */
388706f2543Smrg
389706f2543Smrg
390706f2543Smrg/******************************************************************************
391706f2543Smrg *
392706f2543Smrg * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
393706f2543Smrg *
394706f2543Smrg * Description:
395706f2543Smrg *
396706f2543Smrg *     This function is for processing a DbeDeallocateBackBufferName request.
397706f2543Smrg *     This request frees a drawable ID that was obtained by a
398706f2543Smrg *     DbeAllocateBackBufferName request.
399706f2543Smrg *
400706f2543Smrg * Return Values:
401706f2543Smrg *
402706f2543Smrg *     BadBuffer - buffer to deallocate is not associated with a window
403706f2543Smrg *     Success
404706f2543Smrg *
405706f2543Smrg *****************************************************************************/
406706f2543Smrg
407706f2543Smrgstatic int
408706f2543SmrgProcDbeDeallocateBackBufferName(ClientPtr client)
409706f2543Smrg{
410706f2543Smrg    REQUEST(xDbeDeallocateBackBufferNameReq);
411706f2543Smrg    DbeWindowPrivPtr	pDbeWindowPriv;
412706f2543Smrg    int			rc, i;
413706f2543Smrg    pointer val;
414706f2543Smrg
415706f2543Smrg
416706f2543Smrg    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
417706f2543Smrg
418706f2543Smrg    /* Buffer name must be valid */
419706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
420706f2543Smrg				 dbeWindowPrivResType, client,
421706f2543Smrg				 DixDestroyAccess);
422706f2543Smrg    if (rc != Success)
423706f2543Smrg	return rc;
424706f2543Smrg
425706f2543Smrg    rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
426706f2543Smrg				 client, DixDestroyAccess);
427706f2543Smrg    if (rc != Success)
428706f2543Smrg	return rc;
429706f2543Smrg
430706f2543Smrg    /* Make sure that the id is valid for the window.
431706f2543Smrg     * This is paranoid code since we already looked up the ID by type
432706f2543Smrg     * above.
433706f2543Smrg     */
434706f2543Smrg
435706f2543Smrg    for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
436706f2543Smrg    {
437706f2543Smrg        /* Loop through the ID list to find the ID. */
438706f2543Smrg        if (pDbeWindowPriv->IDs[i] == stuff->buffer)
439706f2543Smrg        {
440706f2543Smrg            break;
441706f2543Smrg        }
442706f2543Smrg    }
443706f2543Smrg
444706f2543Smrg    if (i == pDbeWindowPriv->nBufferIDs)
445706f2543Smrg    {
446706f2543Smrg        /* We did not find the ID in the ID list. */
447706f2543Smrg        client->errorValue = stuff->buffer;
448706f2543Smrg        return dbeErrorBase + DbeBadBuffer;
449706f2543Smrg    }
450706f2543Smrg
451706f2543Smrg    FreeResource(stuff->buffer, RT_NONE);
452706f2543Smrg
453706f2543Smrg    return Success;
454706f2543Smrg
455706f2543Smrg} /* ProcDbeDeallocateBackBufferName() */
456706f2543Smrg
457706f2543Smrg
458706f2543Smrg/******************************************************************************
459706f2543Smrg *
460706f2543Smrg * DBE DIX Procedure: ProcDbeSwapBuffers
461706f2543Smrg *
462706f2543Smrg * Description:
463706f2543Smrg *
464706f2543Smrg *     This function is for processing a DbeSwapBuffers request.
465706f2543Smrg *     This request swaps the buffers for all windows listed, applying the
466706f2543Smrg *     appropriate swap action for each window.
467706f2543Smrg *
468706f2543Smrg * Return Values:
469706f2543Smrg *
470706f2543Smrg *     BadAlloc  - local allocation failed; this return value is not defined
471706f2543Smrg *                 by the protocol
472706f2543Smrg *     BadMatch  - a window in request is not double-buffered; a window in
473706f2543Smrg *                 request is listed more than once
474706f2543Smrg *     BadValue  - invalid swap action is specified; no swap action is
475706f2543Smrg *                 specified
476706f2543Smrg *     BadWindow - a window in request is not valid
477706f2543Smrg *     Success
478706f2543Smrg *
479706f2543Smrg *****************************************************************************/
480706f2543Smrg
481706f2543Smrgstatic int
482706f2543SmrgProcDbeSwapBuffers(ClientPtr client)
483706f2543Smrg{
484706f2543Smrg    REQUEST(xDbeSwapBuffersReq);
485706f2543Smrg    WindowPtr		pWin;
486706f2543Smrg    DbeScreenPrivPtr	pDbeScreenPriv;
487706f2543Smrg    DbeSwapInfoPtr	swapInfo;
488706f2543Smrg    xDbeSwapInfo	*dbeSwapInfo;
489706f2543Smrg    int			error;
490706f2543Smrg    unsigned int i, j;
491706f2543Smrg    unsigned int nStuff;
492706f2543Smrg
493706f2543Smrg
494706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
495706f2543Smrg    nStuff = stuff->n;	/* use local variable for performance. */
496706f2543Smrg
497706f2543Smrg    if (nStuff == 0)
498706f2543Smrg    {
499706f2543Smrg        REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
500706f2543Smrg        return Success;
501706f2543Smrg    }
502706f2543Smrg
503706f2543Smrg    if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
504706f2543Smrg	    return BadAlloc;
505706f2543Smrg    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
506706f2543Smrg
507706f2543Smrg    /* Get to the swap info appended to the end of the request. */
508706f2543Smrg    dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
509706f2543Smrg
510706f2543Smrg    /* Allocate array to record swap information. */
511706f2543Smrg    swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec));
512706f2543Smrg    if (swapInfo == NULL)
513706f2543Smrg    {
514706f2543Smrg        return BadAlloc;
515706f2543Smrg    }
516706f2543Smrg
517706f2543Smrg
518706f2543Smrg    for (i = 0; i < nStuff; i++)
519706f2543Smrg    {
520706f2543Smrg        /* Check all windows to swap. */
521706f2543Smrg
522706f2543Smrg        /* Each window must be a valid window - BadWindow. */
523706f2543Smrg	error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
524706f2543Smrg				DixWriteAccess);
525706f2543Smrg	if (error != Success) {
526706f2543Smrg            free(swapInfo);
527706f2543Smrg	    return error;
528706f2543Smrg        }
529706f2543Smrg
530706f2543Smrg        /* Each window must be double-buffered - BadMatch. */
531706f2543Smrg        if (DBE_WINDOW_PRIV(pWin) == NULL)
532706f2543Smrg        {
533706f2543Smrg            free(swapInfo);
534706f2543Smrg            return BadMatch;
535706f2543Smrg        }
536706f2543Smrg
537706f2543Smrg        /* Each window must only be specified once - BadMatch. */
538706f2543Smrg        for (j = i + 1; j < nStuff; j++)
539706f2543Smrg        {
540706f2543Smrg            if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
541706f2543Smrg            {
542706f2543Smrg                free(swapInfo);
543706f2543Smrg                return BadMatch;
544706f2543Smrg	    }
545706f2543Smrg        }
546706f2543Smrg
547706f2543Smrg        /* Each swap action must be valid - BadValue. */
548706f2543Smrg        if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) &&
549706f2543Smrg            (dbeSwapInfo[i].swapAction != XdbeBackground) &&
550706f2543Smrg            (dbeSwapInfo[i].swapAction != XdbeUntouched ) &&
551706f2543Smrg            (dbeSwapInfo[i].swapAction != XdbeCopied    ))
552706f2543Smrg        {
553706f2543Smrg            free(swapInfo);
554706f2543Smrg            return BadValue;
555706f2543Smrg        }
556706f2543Smrg
557706f2543Smrg        /* Everything checks out OK.  Fill in the swap info array. */
558706f2543Smrg        swapInfo[i].pWindow    = pWin;
559706f2543Smrg        swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
560706f2543Smrg
561706f2543Smrg    } /* for (i = 0; i < nStuff; i++) */
562706f2543Smrg
563706f2543Smrg
564706f2543Smrg    /* Call the DDX routine to perform the swap(s).  The DDX routine should
565706f2543Smrg     * scan the swap list (swap info), swap any buffers that it knows how to
566706f2543Smrg     * handle, delete them from the list, and update nStuff to indicate how
567706f2543Smrg     * many windows it did not handle.
568706f2543Smrg     *
569706f2543Smrg     * This scheme allows a range of sophistication in the DDX SwapBuffers()
570706f2543Smrg     * implementation.  Naive implementations could just swap the first buffer
571706f2543Smrg     * in the list, move the last buffer to the front, decrement nStuff, and
572706f2543Smrg     * return.  The next level of sophistication could be to scan the whole
573706f2543Smrg     * list for windows on the same screen.  Up another level, the DDX routine
574706f2543Smrg     * could deal with cross-screen synchronization.
575706f2543Smrg     */
576706f2543Smrg
577706f2543Smrg    while (nStuff > 0)
578706f2543Smrg    {
579706f2543Smrg        pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
580706f2543Smrg        error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo);
581706f2543Smrg        if (error != Success)
582706f2543Smrg        {
583706f2543Smrg            free(swapInfo);
584706f2543Smrg            return error;
585706f2543Smrg        }
586706f2543Smrg    }
587706f2543Smrg
588706f2543Smrg    free(swapInfo);
589706f2543Smrg    return Success;
590706f2543Smrg
591706f2543Smrg} /* ProcDbeSwapBuffers() */
592706f2543Smrg
593706f2543Smrg
594706f2543Smrg/******************************************************************************
595706f2543Smrg *
596706f2543Smrg * DBE DIX Procedure: ProcDbeBeginIdiom
597706f2543Smrg *
598706f2543Smrg * Description:
599706f2543Smrg *
600706f2543Smrg *     This function is for processing a DbeBeginIdiom request.
601706f2543Smrg *     This request informs the server that a complex swap will immediately
602706f2543Smrg *     follow this request.
603706f2543Smrg *
604706f2543Smrg * Return Values:
605706f2543Smrg *
606706f2543Smrg *     Success
607706f2543Smrg *
608706f2543Smrg *****************************************************************************/
609706f2543Smrg
610706f2543Smrgstatic int
611706f2543SmrgProcDbeBeginIdiom(ClientPtr client)
612706f2543Smrg{
613706f2543Smrg    /* REQUEST(xDbeBeginIdiomReq); */
614706f2543Smrg    DbeScreenPrivPtr	pDbeScreenPriv;
615706f2543Smrg    register int	i;
616706f2543Smrg
617706f2543Smrg
618706f2543Smrg    REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
619706f2543Smrg
620706f2543Smrg    for (i = 0; i < screenInfo.numScreens; i++)
621706f2543Smrg    {
622706f2543Smrg        pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
623706f2543Smrg
624706f2543Smrg        /* Call the DDX begin idiom procedure if there is one. */
625706f2543Smrg        if (pDbeScreenPriv->BeginIdiom)
626706f2543Smrg        {
627706f2543Smrg           (*pDbeScreenPriv->BeginIdiom)(client);
628706f2543Smrg        }
629706f2543Smrg    }
630706f2543Smrg
631706f2543Smrg    return Success;
632706f2543Smrg
633706f2543Smrg} /* ProcDbeBeginIdiom() */
634706f2543Smrg
635706f2543Smrg
636706f2543Smrg/******************************************************************************
637706f2543Smrg *
638706f2543Smrg * DBE DIX Procedure: ProcDbeGetVisualInfo
639706f2543Smrg *
640706f2543Smrg * Description:
641706f2543Smrg *
642706f2543Smrg *     This function is for processing a ProcDbeGetVisualInfo request.
643706f2543Smrg *     This request returns information about which visuals support
644706f2543Smrg *     double buffering.
645706f2543Smrg *
646706f2543Smrg * Return Values:
647706f2543Smrg *
648706f2543Smrg *     BadDrawable - value in screen specifiers is not a valid drawable
649706f2543Smrg *     Success
650706f2543Smrg *
651706f2543Smrg *****************************************************************************/
652706f2543Smrg
653706f2543Smrgstatic int
654706f2543SmrgProcDbeGetVisualInfo(ClientPtr client)
655706f2543Smrg{
656706f2543Smrg    REQUEST(xDbeGetVisualInfoReq);
657706f2543Smrg    DbeScreenPrivPtr		pDbeScreenPriv;
658706f2543Smrg    xDbeGetVisualInfoReply	rep;
659706f2543Smrg    Drawable			*drawables;
660706f2543Smrg    DrawablePtr			*pDrawables = NULL;
661706f2543Smrg    register int		i, j, n, rc;
662706f2543Smrg    register int		count;  /* number of visual infos in reply */
663706f2543Smrg    register int		length; /* length of reply */
664706f2543Smrg    ScreenPtr			pScreen;
665706f2543Smrg    XdbeScreenVisualInfo	*pScrVisInfo;
666706f2543Smrg
667706f2543Smrg
668706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
66948a68b89Smrg    if (stuff->n > UINT32_MAX / sizeof(CARD32))
67048a68b89Smrg        return BadLength;
67148a68b89Smrg    REQUEST_FIXED_SIZE(xDbeGetVisualInfoReq, stuff->n * sizeof(CARD32));
672706f2543Smrg
673706f2543Smrg    if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
674706f2543Smrg	    return BadAlloc;
675706f2543Smrg    /* Make sure any specified drawables are valid. */
676706f2543Smrg    if (stuff->n != 0)
677706f2543Smrg    {
678706f2543Smrg        if (!(pDrawables = (DrawablePtr *)malloc(stuff->n *
679706f2543Smrg                                                 sizeof(DrawablePtr))))
680706f2543Smrg        {
681706f2543Smrg            return BadAlloc;
682706f2543Smrg        }
683706f2543Smrg
684706f2543Smrg        drawables = (Drawable *)&stuff[1];
685706f2543Smrg
686706f2543Smrg        for (i = 0; i < stuff->n; i++)
687706f2543Smrg        {
688706f2543Smrg	    rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0,
689706f2543Smrg				   DixGetAttrAccess);
690706f2543Smrg	    if (rc != Success) {
691706f2543Smrg                free(pDrawables);
692706f2543Smrg                return rc;
693706f2543Smrg            }
694706f2543Smrg        }
695706f2543Smrg    }
696706f2543Smrg
697706f2543Smrg    count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
698706f2543Smrg    if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo))))
699706f2543Smrg    {
700706f2543Smrg        free(pDrawables);
701706f2543Smrg
702706f2543Smrg        return BadAlloc;
703706f2543Smrg    }
704706f2543Smrg
705706f2543Smrg    length = 0;
706706f2543Smrg
707706f2543Smrg    for (i = 0; i < count; i++)
708706f2543Smrg    {
709706f2543Smrg        pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
710706f2543Smrg                                    pDrawables[i]->pScreen;
711706f2543Smrg        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
712706f2543Smrg
713706f2543Smrg	rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
714706f2543Smrg        if (rc != Success)
715706f2543Smrg            goto freeScrVisInfo;
716706f2543Smrg
717706f2543Smrg        if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
718706f2543Smrg        {
719706f2543Smrg            /* We failed to alloc pScrVisInfo[i].visinfo. */
720706f2543Smrg            rc = BadAlloc;
721706f2543Smrg
722706f2543Smrg            /* Free visinfos that we allocated for previous screen infos.*/
723706f2543Smrg            goto freeScrVisInfo;
724706f2543Smrg        }
725706f2543Smrg
726706f2543Smrg        /* Account for n, number of xDbeVisInfo items in list. */
727706f2543Smrg        length += sizeof(CARD32);
728706f2543Smrg
729706f2543Smrg        /* Account for n xDbeVisInfo items */
730706f2543Smrg        length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
731706f2543Smrg    }
732706f2543Smrg
733706f2543Smrg    rep.type           = X_Reply;
734706f2543Smrg    rep.sequenceNumber = client->sequence;
735706f2543Smrg    rep.length         = bytes_to_int32(length);
736706f2543Smrg    rep.m              = count;
737706f2543Smrg
738706f2543Smrg    if (client->swapped)
739706f2543Smrg    {
740706f2543Smrg        swaps(&rep.sequenceNumber, n);
741706f2543Smrg        swapl(&rep.length, n);
742706f2543Smrg        swapl(&rep.m, n);
743706f2543Smrg    }
744706f2543Smrg
745706f2543Smrg    /* Send off reply. */
746706f2543Smrg    WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep);
747706f2543Smrg
748706f2543Smrg    for (i = 0; i < count; i++)
749706f2543Smrg    {
750706f2543Smrg        CARD32	data32;
751706f2543Smrg
752706f2543Smrg        /* For each screen in the reply, send off the visual info */
753706f2543Smrg
754706f2543Smrg        /* Send off number of visuals. */
755706f2543Smrg        data32 = (CARD32)pScrVisInfo[i].count;
756706f2543Smrg
757706f2543Smrg        if (client->swapped)
758706f2543Smrg        {
759706f2543Smrg            swapl(&data32, n);
760706f2543Smrg        }
761706f2543Smrg
762706f2543Smrg        WriteToClient(client, sizeof(CARD32), (char *)&data32);
763706f2543Smrg
764706f2543Smrg        /* Now send off visual info items. */
765706f2543Smrg        for (j = 0; j < pScrVisInfo[i].count; j++)
766706f2543Smrg        {
767706f2543Smrg            xDbeVisInfo		visInfo;
768706f2543Smrg
769706f2543Smrg            /* Copy the data in the client data structure to a protocol
770706f2543Smrg             * data structure.  We will send data to the client from the
771706f2543Smrg             * protocol data structure.
772706f2543Smrg             */
773706f2543Smrg
774706f2543Smrg            visInfo.visualID  = (CARD32)pScrVisInfo[i].visinfo[j].visual;
775706f2543Smrg            visInfo.depth     = (CARD8) pScrVisInfo[i].visinfo[j].depth;
776706f2543Smrg            visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
777706f2543Smrg
778706f2543Smrg            if (client->swapped)
779706f2543Smrg            {
780706f2543Smrg                swapl(&visInfo.visualID, n);
781706f2543Smrg
782706f2543Smrg                /* We do not need to swap depth and perfLevel since they are
783706f2543Smrg                 * already 1 byte quantities.
784706f2543Smrg                 */
785706f2543Smrg            }
786706f2543Smrg
787706f2543Smrg            /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
788706f2543Smrg            WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID);
789706f2543Smrg        }
790706f2543Smrg    }
791706f2543Smrg
792706f2543Smrg    rc = Success;
793706f2543Smrg
794706f2543Smrg  freeScrVisInfo:
795706f2543Smrg    /* Clean up memory. */
796706f2543Smrg    for (i = 0; i < count; i++)
797706f2543Smrg    {
798706f2543Smrg        free(pScrVisInfo[i].visinfo);
799706f2543Smrg    }
800706f2543Smrg    free(pScrVisInfo);
801706f2543Smrg
802706f2543Smrg    free(pDrawables);
803706f2543Smrg
804706f2543Smrg    return rc;
805706f2543Smrg
806706f2543Smrg} /* ProcDbeGetVisualInfo() */
807706f2543Smrg
808706f2543Smrg
809706f2543Smrg/******************************************************************************
810706f2543Smrg *
811706f2543Smrg * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
812706f2543Smrg *
813706f2543Smrg * Description:
814706f2543Smrg *
815706f2543Smrg *     This function is for processing a ProcDbeGetbackBufferAttributes
816706f2543Smrg *     request.  This request returns information about a back buffer.
817706f2543Smrg *
818706f2543Smrg * Return Values:
819706f2543Smrg *
820706f2543Smrg *     Success
821706f2543Smrg *
822706f2543Smrg *****************************************************************************/
823706f2543Smrg
824706f2543Smrgstatic int
825706f2543SmrgProcDbeGetBackBufferAttributes(ClientPtr client)
826706f2543Smrg{
827706f2543Smrg    REQUEST(xDbeGetBackBufferAttributesReq);
828706f2543Smrg    xDbeGetBackBufferAttributesReply	rep;
829706f2543Smrg    DbeWindowPrivPtr			pDbeWindowPriv;
830706f2543Smrg    int					rc, n;
831706f2543Smrg
832706f2543Smrg
833706f2543Smrg    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
834706f2543Smrg
835706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
836706f2543Smrg				 dbeWindowPrivResType, client,
837706f2543Smrg				 DixGetAttrAccess);
838706f2543Smrg    if (rc == Success)
839706f2543Smrg    {
840706f2543Smrg        rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
841706f2543Smrg    }
842706f2543Smrg    else
843706f2543Smrg    {
844706f2543Smrg        rep.attributes = None;
845706f2543Smrg    }
846706f2543Smrg
847706f2543Smrg    rep.type           = X_Reply;
848706f2543Smrg    rep.sequenceNumber = client->sequence;
849706f2543Smrg    rep.length         = 0;
850706f2543Smrg
851706f2543Smrg    if (client->swapped)
852706f2543Smrg    {
853706f2543Smrg        swaps(&rep.sequenceNumber, n);
854706f2543Smrg        swapl(&rep.length, n);
855706f2543Smrg        swapl(&rep.attributes, n);
856706f2543Smrg    }
857706f2543Smrg
858706f2543Smrg    WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
859706f2543Smrg                  (char *)&rep);
860706f2543Smrg    return Success;
861706f2543Smrg
862706f2543Smrg} /* ProcDbeGetbackBufferAttributes() */
863706f2543Smrg
864706f2543Smrg
865706f2543Smrg/******************************************************************************
866706f2543Smrg *
867706f2543Smrg * DBE DIX Procedure: ProcDbeDispatch
868706f2543Smrg *
869706f2543Smrg * Description:
870706f2543Smrg *
871706f2543Smrg *     This function dispatches DBE requests.
872706f2543Smrg *
873706f2543Smrg *****************************************************************************/
874706f2543Smrg
875706f2543Smrgstatic int
876706f2543SmrgProcDbeDispatch(ClientPtr client)
877706f2543Smrg{
878706f2543Smrg    REQUEST(xReq);
879706f2543Smrg
880706f2543Smrg
881706f2543Smrg    switch (stuff->data)
882706f2543Smrg    {
883706f2543Smrg        case X_DbeGetVersion:
884706f2543Smrg            return(ProcDbeGetVersion(client));
885706f2543Smrg
886706f2543Smrg        case X_DbeAllocateBackBufferName:
887706f2543Smrg            return(ProcDbeAllocateBackBufferName(client));
888706f2543Smrg
889706f2543Smrg        case X_DbeDeallocateBackBufferName:
890706f2543Smrg            return(ProcDbeDeallocateBackBufferName(client));
891706f2543Smrg
892706f2543Smrg        case X_DbeSwapBuffers:
893706f2543Smrg            return(ProcDbeSwapBuffers(client));
894706f2543Smrg
895706f2543Smrg        case X_DbeBeginIdiom:
896706f2543Smrg            return(ProcDbeBeginIdiom(client));
897706f2543Smrg
898706f2543Smrg        case X_DbeEndIdiom:
899706f2543Smrg            return Success;
900706f2543Smrg
901706f2543Smrg        case X_DbeGetVisualInfo:
902706f2543Smrg            return(ProcDbeGetVisualInfo(client));
903706f2543Smrg
904706f2543Smrg        case X_DbeGetBackBufferAttributes:
905706f2543Smrg            return(ProcDbeGetBackBufferAttributes(client));
906706f2543Smrg
907706f2543Smrg        default:
908706f2543Smrg            return BadRequest;
909706f2543Smrg    }
910706f2543Smrg
911706f2543Smrg} /* ProcDbeDispatch() */
912706f2543Smrg
913706f2543Smrg
914706f2543Smrg/******************************************************************************
915706f2543Smrg *
916706f2543Smrg * DBE DIX Procedure: SProcDbeGetVersion
917706f2543Smrg *
918706f2543Smrg * Description:
919706f2543Smrg *
920706f2543Smrg *     This function is for processing a DbeGetVersion request on a swapped
921706f2543Smrg *     server.  This request returns the major and minor version numbers of
922706f2543Smrg *     this extension.
923706f2543Smrg *
924706f2543Smrg * Return Values:
925706f2543Smrg *
926706f2543Smrg *     Success
927706f2543Smrg *
928706f2543Smrg *****************************************************************************/
929706f2543Smrg
930706f2543Smrgstatic int
931706f2543SmrgSProcDbeGetVersion(ClientPtr client)
932706f2543Smrg{
933706f2543Smrg    REQUEST(xDbeGetVersionReq);
934706f2543Smrg    register int	n;
935706f2543Smrg
936706f2543Smrg
937706f2543Smrg    swaps(&stuff->length, n);
938706f2543Smrg    return(ProcDbeGetVersion(client));
939706f2543Smrg
940706f2543Smrg} /* SProcDbeGetVersion() */
941706f2543Smrg
942706f2543Smrg
943706f2543Smrg/******************************************************************************
944706f2543Smrg *
945706f2543Smrg * DBE DIX Procedure: SProcDbeAllocateBackBufferName
946706f2543Smrg *
947706f2543Smrg * Description:
948706f2543Smrg *
949706f2543Smrg *     This function is for processing a DbeAllocateBackBufferName request on
950706f2543Smrg *     a swapped server.  This request allocates a drawable ID used to refer
951706f2543Smrg *     to the back buffer of a window.
952706f2543Smrg *
953706f2543Smrg * Return Values:
954706f2543Smrg *
955706f2543Smrg *     BadAlloc    - server can not allocate resources
956706f2543Smrg *     BadIDChoice - id is out of range for client; id is already in use
957706f2543Smrg *     BadMatch    - window is not an InputOutput window;
958706f2543Smrg *                   visual of window is not on list returned by
959706f2543Smrg *                   DBEGetVisualInfo;
960706f2543Smrg *     BadValue    - invalid swap action is specified
961706f2543Smrg *     BadWindow   - window is not a valid window
962706f2543Smrg *     Success
963706f2543Smrg *
964706f2543Smrg *****************************************************************************/
965706f2543Smrg
966706f2543Smrgstatic int
967706f2543SmrgSProcDbeAllocateBackBufferName(ClientPtr client)
968706f2543Smrg{
969706f2543Smrg    REQUEST(xDbeAllocateBackBufferNameReq);
970706f2543Smrg    register int	n;
971706f2543Smrg
972706f2543Smrg    swaps(&stuff->length, n);
973706f2543Smrg    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
974706f2543Smrg
975706f2543Smrg    swapl(&stuff->window, n);
976706f2543Smrg    swapl(&stuff->buffer, n);
977706f2543Smrg    /* stuff->swapAction is a byte.  We do not need to swap this field. */
978706f2543Smrg
979706f2543Smrg    return(ProcDbeAllocateBackBufferName(client));
980706f2543Smrg
981706f2543Smrg} /* SProcDbeAllocateBackBufferName() */
982706f2543Smrg
983706f2543Smrg
984706f2543Smrg/******************************************************************************
985706f2543Smrg *
986706f2543Smrg * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
987706f2543Smrg *
988706f2543Smrg * Description:
989706f2543Smrg *
990706f2543Smrg *     This function is for processing a DbeDeallocateBackBufferName request
991706f2543Smrg *     on a swapped server.  This request frees a drawable ID that was
992706f2543Smrg *     obtained by a DbeAllocateBackBufferName request.
993706f2543Smrg *
994706f2543Smrg * Return Values:
995706f2543Smrg *
996706f2543Smrg *     BadBuffer - buffer to deallocate is not associated with a window
997706f2543Smrg *     Success
998706f2543Smrg *
999706f2543Smrg *****************************************************************************/
1000706f2543Smrg
1001706f2543Smrgstatic int
1002706f2543SmrgSProcDbeDeallocateBackBufferName(ClientPtr client)
1003706f2543Smrg{
1004706f2543Smrg    REQUEST (xDbeDeallocateBackBufferNameReq);
1005706f2543Smrg    register int	n;
1006706f2543Smrg
1007706f2543Smrg
1008706f2543Smrg    swaps(&stuff->length, n);
1009706f2543Smrg    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
1010706f2543Smrg
1011706f2543Smrg    swapl(&stuff->buffer, n);
1012706f2543Smrg
1013706f2543Smrg    return(ProcDbeDeallocateBackBufferName(client));
1014706f2543Smrg
1015706f2543Smrg} /* SProcDbeDeallocateBackBufferName() */
1016706f2543Smrg
1017706f2543Smrg
1018706f2543Smrg/******************************************************************************
1019706f2543Smrg *
1020706f2543Smrg * DBE DIX Procedure: SProcDbeSwapBuffers
1021706f2543Smrg *
1022706f2543Smrg * Description:
1023706f2543Smrg *
1024706f2543Smrg *     This function is for processing a DbeSwapBuffers request on a swapped
1025706f2543Smrg *     server.  This request swaps the buffers for all windows listed,
1026706f2543Smrg *     applying the appropriate swap action for each window.
1027706f2543Smrg *
1028706f2543Smrg * Return Values:
1029706f2543Smrg *
1030706f2543Smrg *     BadMatch  - a window in request is not double-buffered; a window in
1031706f2543Smrg *                 request is listed more than once; all windows in request do
1032706f2543Smrg *                 not have the same root
1033706f2543Smrg *     BadValue  - invalid swap action is specified
1034706f2543Smrg *     BadWindow - a window in request is not valid
1035706f2543Smrg *     Success
1036706f2543Smrg *
1037706f2543Smrg *****************************************************************************/
1038706f2543Smrg
1039706f2543Smrgstatic int
1040706f2543SmrgSProcDbeSwapBuffers(ClientPtr client)
1041706f2543Smrg{
1042706f2543Smrg    REQUEST(xDbeSwapBuffersReq);
1043706f2543Smrg    unsigned int	i, n;
1044706f2543Smrg    xDbeSwapInfo	*pSwapInfo;
1045706f2543Smrg
1046706f2543Smrg
1047706f2543Smrg    swaps(&stuff->length, n);
1048706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
1049706f2543Smrg
1050706f2543Smrg    swapl(&stuff->n, n);
1051706f2543Smrg    if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
105248a68b89Smrg        return BadLength;
1053706f2543Smrg    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
1054706f2543Smrg
1055706f2543Smrg    if (stuff->n != 0)
1056706f2543Smrg    {
1057706f2543Smrg        pSwapInfo = (xDbeSwapInfo *)stuff+1;
1058706f2543Smrg
1059706f2543Smrg        /* The swap info following the fix part of this request is a window(32)
1060706f2543Smrg         * followed by a 1 byte swap action and then 3 pad bytes.  We only need
1061706f2543Smrg         * to swap the window information.
1062706f2543Smrg         */
1063706f2543Smrg        for (i = 0; i < stuff->n; i++)
1064706f2543Smrg        {
1065706f2543Smrg            swapl(&pSwapInfo->window, n);
1066706f2543Smrg        }
1067706f2543Smrg    }
1068706f2543Smrg
1069706f2543Smrg    return(ProcDbeSwapBuffers(client));
1070706f2543Smrg
1071706f2543Smrg} /* SProcDbeSwapBuffers() */
1072706f2543Smrg
1073706f2543Smrg
1074706f2543Smrg/******************************************************************************
1075706f2543Smrg *
1076706f2543Smrg * DBE DIX Procedure: SProcDbeBeginIdiom
1077706f2543Smrg *
1078706f2543Smrg * Description:
1079706f2543Smrg *
1080706f2543Smrg *     This function is for processing a DbeBeginIdiom request on a swapped
1081706f2543Smrg *     server.  This request informs the server that a complex swap will
1082706f2543Smrg *     immediately follow this request.
1083706f2543Smrg *
1084706f2543Smrg * Return Values:
1085706f2543Smrg *
1086706f2543Smrg *     Success
1087706f2543Smrg *
1088706f2543Smrg *****************************************************************************/
1089706f2543Smrg
1090706f2543Smrgstatic int
1091706f2543SmrgSProcDbeBeginIdiom(ClientPtr client)
1092706f2543Smrg{
1093706f2543Smrg    REQUEST(xDbeBeginIdiomReq);
1094706f2543Smrg    register int	n;
1095706f2543Smrg
1096706f2543Smrg    swaps(&stuff->length, n);
1097706f2543Smrg    return(ProcDbeBeginIdiom(client));
1098706f2543Smrg
1099706f2543Smrg} /* SProcDbeBeginIdiom() */
1100706f2543Smrg
1101706f2543Smrg
1102706f2543Smrg/******************************************************************************
1103706f2543Smrg *
1104706f2543Smrg * DBE DIX Procedure: SProcDbeGetVisualInfo
1105706f2543Smrg *
1106706f2543Smrg * Description:
1107706f2543Smrg *
1108706f2543Smrg *     This function is for processing a ProcDbeGetVisualInfo request on a
1109706f2543Smrg *     swapped server.  This request returns information about which visuals
1110706f2543Smrg *     support double buffering.
1111706f2543Smrg *
1112706f2543Smrg * Return Values:
1113706f2543Smrg *
1114706f2543Smrg *     BadDrawable - value in screen specifiers is not a valid drawable
1115706f2543Smrg *     Success
1116706f2543Smrg *
1117706f2543Smrg *****************************************************************************/
1118706f2543Smrg
1119706f2543Smrgstatic int
1120706f2543SmrgSProcDbeGetVisualInfo(ClientPtr client)
1121706f2543Smrg{
1122706f2543Smrg    REQUEST(xDbeGetVisualInfoReq);
1123706f2543Smrg    register int	n;
1124706f2543Smrg
1125706f2543Smrg
1126706f2543Smrg    swaps(&stuff->length, n);
1127706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
1128706f2543Smrg
1129706f2543Smrg    swapl(&stuff->n, n);
1130706f2543Smrg    SwapRestL(stuff);
1131706f2543Smrg
1132706f2543Smrg    return(ProcDbeGetVisualInfo(client));
1133706f2543Smrg
1134706f2543Smrg} /* SProcDbeGetVisualInfo() */
1135706f2543Smrg
1136706f2543Smrg
1137706f2543Smrg/******************************************************************************
1138706f2543Smrg *
1139706f2543Smrg * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
1140706f2543Smrg *
1141706f2543Smrg * Description:
1142706f2543Smrg *
1143706f2543Smrg *     This function is for processing a ProcDbeGetbackBufferAttributes
1144706f2543Smrg *     request on a swapped server.  This request returns information about a
1145706f2543Smrg *     back buffer.
1146706f2543Smrg *
1147706f2543Smrg * Return Values:
1148706f2543Smrg *
1149706f2543Smrg *     Success
1150706f2543Smrg *
1151706f2543Smrg *****************************************************************************/
1152706f2543Smrg
1153706f2543Smrgstatic int
1154706f2543SmrgSProcDbeGetBackBufferAttributes(ClientPtr client)
1155706f2543Smrg{
1156706f2543Smrg    REQUEST (xDbeGetBackBufferAttributesReq);
1157706f2543Smrg    register int	n;
1158706f2543Smrg
1159706f2543Smrg    swaps(&stuff->length, n);
1160706f2543Smrg    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
1161706f2543Smrg
1162706f2543Smrg    swapl(&stuff->buffer, n);
1163706f2543Smrg
1164706f2543Smrg    return(ProcDbeGetBackBufferAttributes(client));
1165706f2543Smrg
1166706f2543Smrg} /* SProcDbeGetBackBufferAttributes() */
1167706f2543Smrg
1168706f2543Smrg
1169706f2543Smrg/******************************************************************************
1170706f2543Smrg *
1171706f2543Smrg * DBE DIX Procedure: SProcDbeDispatch
1172706f2543Smrg *
1173706f2543Smrg * Description:
1174706f2543Smrg *
1175706f2543Smrg *     This function dispatches DBE requests on a swapped server.
1176706f2543Smrg *
1177706f2543Smrg *****************************************************************************/
1178706f2543Smrg
1179706f2543Smrgstatic int
1180706f2543SmrgSProcDbeDispatch(ClientPtr client)
1181706f2543Smrg{
1182706f2543Smrg    REQUEST(xReq);
1183706f2543Smrg
1184706f2543Smrg
1185706f2543Smrg    switch (stuff->data)
1186706f2543Smrg    {
1187706f2543Smrg        case X_DbeGetVersion:
1188706f2543Smrg            return(SProcDbeGetVersion(client));
1189706f2543Smrg
1190706f2543Smrg        case X_DbeAllocateBackBufferName:
1191706f2543Smrg            return(SProcDbeAllocateBackBufferName(client));
1192706f2543Smrg
1193706f2543Smrg        case X_DbeDeallocateBackBufferName:
1194706f2543Smrg            return(SProcDbeDeallocateBackBufferName(client));
1195706f2543Smrg
1196706f2543Smrg        case X_DbeSwapBuffers:
1197706f2543Smrg            return(SProcDbeSwapBuffers(client));
1198706f2543Smrg
1199706f2543Smrg        case X_DbeBeginIdiom:
1200706f2543Smrg            return(SProcDbeBeginIdiom(client));
1201706f2543Smrg
1202706f2543Smrg        case X_DbeEndIdiom:
1203706f2543Smrg            return Success;
1204706f2543Smrg
1205706f2543Smrg        case X_DbeGetVisualInfo:
1206706f2543Smrg            return(SProcDbeGetVisualInfo(client));
1207706f2543Smrg
1208706f2543Smrg        case X_DbeGetBackBufferAttributes:
1209706f2543Smrg            return(SProcDbeGetBackBufferAttributes(client));
1210706f2543Smrg
1211706f2543Smrg        default:
1212706f2543Smrg            return BadRequest;
1213706f2543Smrg    }
1214706f2543Smrg
1215706f2543Smrg} /* SProcDbeDispatch() */
1216706f2543Smrg
1217706f2543Smrg
1218706f2543Smrg/******************************************************************************
1219706f2543Smrg *
1220706f2543Smrg * DBE DIX Procedure: DbeSetupBackgroundPainter
1221706f2543Smrg *
1222706f2543Smrg * Description:
1223706f2543Smrg *
1224706f2543Smrg *     This function sets up pGC to clear pixmaps.
1225706f2543Smrg *
1226706f2543Smrg * Return Values:
1227706f2543Smrg *
1228706f2543Smrg *     TRUE  - setup was successful
1229706f2543Smrg *     FALSE - the window's background state is NONE
1230706f2543Smrg *
1231706f2543Smrg *****************************************************************************/
1232706f2543Smrg
1233706f2543Smrgstatic Bool
1234706f2543SmrgDbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
1235706f2543Smrg{
1236706f2543Smrg    ChangeGCVal	gcvalues[4];
1237706f2543Smrg    int		ts_x_origin, ts_y_origin;
1238706f2543Smrg    PixUnion	background;
1239706f2543Smrg    int		backgroundState;
1240706f2543Smrg    Mask	gcmask;
1241706f2543Smrg
1242706f2543Smrg
1243706f2543Smrg    /* First take care of any ParentRelative stuff by altering the
1244706f2543Smrg     * tile/stipple origin to match the coordinates of the upper-left
1245706f2543Smrg     * corner of the first ancestor without a ParentRelative background.
1246706f2543Smrg     * This coordinate is, of course, negative.
1247706f2543Smrg     */
1248706f2543Smrg    ts_x_origin = ts_y_origin = 0;
1249706f2543Smrg    while (pWin->backgroundState == ParentRelative)
1250706f2543Smrg    {
1251706f2543Smrg        ts_x_origin -= pWin->origin.x;
1252706f2543Smrg        ts_y_origin -= pWin->origin.y;
1253706f2543Smrg
1254706f2543Smrg        pWin = pWin->parent;
1255706f2543Smrg    }
1256706f2543Smrg    backgroundState = pWin->backgroundState;
1257706f2543Smrg    background      = pWin->background;
1258706f2543Smrg
1259706f2543Smrg    switch (backgroundState)
1260706f2543Smrg    {
1261706f2543Smrg        case BackgroundPixel:
1262706f2543Smrg            gcvalues[0].val = background.pixel;
1263706f2543Smrg            gcvalues[1].val = FillSolid;
1264706f2543Smrg            gcmask = GCForeground|GCFillStyle;
1265706f2543Smrg            break;
1266706f2543Smrg
1267706f2543Smrg        case BackgroundPixmap:
1268706f2543Smrg            gcvalues[0].val = FillTiled;
1269706f2543Smrg            gcvalues[1].ptr = background.pixmap;
1270706f2543Smrg            gcvalues[2].val = ts_x_origin;
1271706f2543Smrg            gcvalues[3].val = ts_y_origin;
1272706f2543Smrg            gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
1273706f2543Smrg            break;
1274706f2543Smrg
1275706f2543Smrg        default:
1276706f2543Smrg            /* pWin->backgroundState == None */
1277706f2543Smrg            return FALSE;
1278706f2543Smrg    }
1279706f2543Smrg
1280706f2543Smrg    return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
1281706f2543Smrg} /* DbeSetupBackgroundPainter() */
1282706f2543Smrg
1283706f2543Smrg
1284706f2543Smrg/******************************************************************************
1285706f2543Smrg *
1286706f2543Smrg * DBE DIX Procedure: DbeDrawableDelete
1287706f2543Smrg *
1288706f2543Smrg * Description:
1289706f2543Smrg *
1290706f2543Smrg *     This is the resource delete function for dbeDrawableResType.
1291706f2543Smrg *     It is registered when the drawable resource type is created in
1292706f2543Smrg *     DbeExtensionInit().
1293706f2543Smrg *
1294706f2543Smrg *     To make resource deletion simple, we do not do anything in this function
1295706f2543Smrg *     and leave all resource deleteion to DbeWindowPrivDelete(), which will
1296706f2543Smrg *     eventually be called or already has been called.  Deletion functions are
1297706f2543Smrg *     not guaranteed to be called in any particular order.
1298706f2543Smrg *
1299706f2543Smrg *****************************************************************************/
1300706f2543Smrgstatic int
1301706f2543SmrgDbeDrawableDelete(pointer pDrawable, XID id)
1302706f2543Smrg{
1303706f2543Smrg    return Success;
1304706f2543Smrg
1305706f2543Smrg} /* DbeDrawableDelete() */
1306706f2543Smrg
1307706f2543Smrg
1308706f2543Smrg/******************************************************************************
1309706f2543Smrg *
1310706f2543Smrg * DBE DIX Procedure: DbeWindowPrivDelete
1311706f2543Smrg *
1312706f2543Smrg * Description:
1313706f2543Smrg *
1314706f2543Smrg *     This is the resource delete function for dbeWindowPrivResType.
1315706f2543Smrg *     It is registered when the drawable resource type is created in
1316706f2543Smrg *     DbeExtensionInit().
1317706f2543Smrg *
1318706f2543Smrg *****************************************************************************/
1319706f2543Smrgstatic int
1320706f2543SmrgDbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
1321706f2543Smrg{
1322706f2543Smrg    DbeScreenPrivPtr	pDbeScreenPriv;
1323706f2543Smrg    DbeWindowPrivPtr	pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv;
1324706f2543Smrg    int			i;
1325706f2543Smrg
1326706f2543Smrg
1327706f2543Smrg    /*
1328706f2543Smrg     **************************************************************************
1329706f2543Smrg     ** Remove the buffer ID from the ID array.
1330706f2543Smrg     **************************************************************************
1331706f2543Smrg     */
1332706f2543Smrg
1333706f2543Smrg    /* Find the ID in the ID array. */
1334706f2543Smrg    i = 0;
1335706f2543Smrg    while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id))
1336706f2543Smrg    {
1337706f2543Smrg        i++;
1338706f2543Smrg    }
1339706f2543Smrg
1340706f2543Smrg    if (i == pDbeWindowPriv->nBufferIDs)
1341706f2543Smrg    {
1342706f2543Smrg        /* We did not find the ID in the array.  We should never get here. */
1343706f2543Smrg        return BadValue;
1344706f2543Smrg    }
1345706f2543Smrg
1346706f2543Smrg    /* Remove the ID from the array. */
1347706f2543Smrg
1348706f2543Smrg    if (i < (pDbeWindowPriv->nBufferIDs - 1))
1349706f2543Smrg    {
1350706f2543Smrg        /* Compress the buffer ID array, overwriting the ID in the process. */
1351706f2543Smrg        memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1],
1352706f2543Smrg            (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
1353706f2543Smrg    }
1354706f2543Smrg    else
1355706f2543Smrg    {
1356706f2543Smrg        /* We are removing the last ID in the array, in which case, the
1357706f2543Smrg         * assignement below is all that we need to do.
1358706f2543Smrg         */
1359706f2543Smrg    }
1360706f2543Smrg    pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
1361706f2543Smrg
1362706f2543Smrg    pDbeWindowPriv->nBufferIDs--;
1363706f2543Smrg
1364706f2543Smrg    /* If an extended array was allocated, then check to see if the remaining
1365706f2543Smrg     * buffer IDs will fit in the static array.
1366706f2543Smrg     */
1367706f2543Smrg
1368706f2543Smrg    if ((pDbeWindowPriv->maxAvailableIDs >  DBE_INIT_MAX_IDS) &&
1369706f2543Smrg        (pDbeWindowPriv->nBufferIDs      == DBE_INIT_MAX_IDS))
1370706f2543Smrg    {
1371706f2543Smrg        /* Copy the IDs back into the static array. */
1372706f2543Smrg        memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
1373706f2543Smrg               DBE_INIT_MAX_IDS * sizeof(XID));
1374706f2543Smrg
1375706f2543Smrg        /* Free the extended array; use the static array. */
1376706f2543Smrg        free(pDbeWindowPriv->IDs);
1377706f2543Smrg        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
1378706f2543Smrg        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
1379706f2543Smrg    }
1380706f2543Smrg
1381706f2543Smrg
1382706f2543Smrg    /*
1383706f2543Smrg     **************************************************************************
1384706f2543Smrg     ** Perform DDX level tasks.
1385706f2543Smrg     **************************************************************************
1386706f2543Smrg     */
1387706f2543Smrg
1388706f2543Smrg    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(
1389706f2543Smrg                         (DbeWindowPrivPtr)pDbeWindowPriv);
1390706f2543Smrg    (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id);
1391706f2543Smrg
1392706f2543Smrg
1393706f2543Smrg    /*
1394706f2543Smrg     **************************************************************************
1395706f2543Smrg     ** Perform miscellaneous tasks if this is the last buffer associated
1396706f2543Smrg     ** with the window.
1397706f2543Smrg     **************************************************************************
1398706f2543Smrg     */
1399706f2543Smrg
1400706f2543Smrg    if (pDbeWindowPriv->nBufferIDs == 0)
1401706f2543Smrg    {
1402706f2543Smrg        /* Reset the DBE window priv pointer. */
1403706f2543Smrg	dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
1404706f2543Smrg		      NULL);
1405706f2543Smrg
1406706f2543Smrg        /* We are done with the window priv. */
1407706f2543Smrg	dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW);
1408706f2543Smrg    }
1409706f2543Smrg
1410706f2543Smrg    return Success;
1411706f2543Smrg
1412706f2543Smrg} /* DbeWindowPrivDelete() */
1413706f2543Smrg
1414706f2543Smrg
1415706f2543Smrg/******************************************************************************
1416706f2543Smrg *
1417706f2543Smrg * DBE DIX Procedure: DbeResetProc
1418706f2543Smrg *
1419706f2543Smrg * Description:
1420706f2543Smrg *
1421706f2543Smrg *     This routine is called at the end of every server generation.
1422706f2543Smrg *     It deallocates any memory reserved for the extension and performs any
1423706f2543Smrg *     other tasks related to shutting down the extension.
1424706f2543Smrg *
1425706f2543Smrg *****************************************************************************/
1426706f2543Smrgstatic void
1427706f2543SmrgDbeResetProc(ExtensionEntry *extEntry)
1428706f2543Smrg{
1429706f2543Smrg    int			i;
1430706f2543Smrg    ScreenPtr		pScreen;
1431706f2543Smrg    DbeScreenPrivPtr	pDbeScreenPriv;
1432706f2543Smrg
1433706f2543Smrg    for (i = 0; i < screenInfo.numScreens; i++)
1434706f2543Smrg    {
1435706f2543Smrg	pScreen = screenInfo.screens[i];
1436706f2543Smrg	pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1437706f2543Smrg
1438706f2543Smrg	if (pDbeScreenPriv)
1439706f2543Smrg	{
1440706f2543Smrg            /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/
1441706f2543Smrg            pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1442706f2543Smrg
1443706f2543Smrg	    if (pDbeScreenPriv->ResetProc)
1444706f2543Smrg		(*pDbeScreenPriv->ResetProc)(pScreen);
1445706f2543Smrg
1446706f2543Smrg	    free(pDbeScreenPriv);
1447706f2543Smrg	}
1448706f2543Smrg    }
1449706f2543Smrg} /* DbeResetProc() */
1450706f2543Smrg
1451706f2543Smrg
1452706f2543Smrg/******************************************************************************
1453706f2543Smrg *
1454706f2543Smrg * DBE DIX Procedure: DbeDestroyWindow
1455706f2543Smrg *
1456706f2543Smrg * Description:
1457706f2543Smrg *
1458706f2543Smrg *     This is the wrapper for pScreen->DestroyWindow.
1459706f2543Smrg *     This function frees buffer resources for a window before it is
1460706f2543Smrg *     destroyed.
1461706f2543Smrg *
1462706f2543Smrg *****************************************************************************/
1463706f2543Smrg
1464706f2543Smrgstatic Bool
1465706f2543SmrgDbeDestroyWindow(WindowPtr pWin)
1466706f2543Smrg{
1467706f2543Smrg    DbeScreenPrivPtr	pDbeScreenPriv;
1468706f2543Smrg    DbeWindowPrivPtr	pDbeWindowPriv;
1469706f2543Smrg    ScreenPtr		pScreen;
1470706f2543Smrg    Bool		ret;
1471706f2543Smrg
1472706f2543Smrg
1473706f2543Smrg    /*
1474706f2543Smrg     **************************************************************************
1475706f2543Smrg     ** 1. Unwrap the member routine.
1476706f2543Smrg     **************************************************************************
1477706f2543Smrg     */
1478706f2543Smrg
1479706f2543Smrg    pScreen                = pWin->drawable.pScreen;
1480706f2543Smrg    pDbeScreenPriv         = DBE_SCREEN_PRIV(pScreen);
1481706f2543Smrg    pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1482706f2543Smrg
1483706f2543Smrg    /*
1484706f2543Smrg     **************************************************************************
1485706f2543Smrg     ** 2. Do any work necessary before the member routine is called.
1486706f2543Smrg     **
1487706f2543Smrg     **    Call the window priv delete function for all buffer IDs associated
1488706f2543Smrg     **    with this window.
1489706f2543Smrg     **************************************************************************
1490706f2543Smrg     */
1491706f2543Smrg
1492706f2543Smrg    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
1493706f2543Smrg    {
1494706f2543Smrg        while (pDbeWindowPriv)
1495706f2543Smrg        {
1496706f2543Smrg            /* *DbeWinPrivDelete() will free the window private and set it to
1497706f2543Smrg             * NULL if there are no more buffer IDs associated with this
1498706f2543Smrg             * window.
1499706f2543Smrg             */
1500706f2543Smrg            FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
1501706f2543Smrg            pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
1502706f2543Smrg        }
1503706f2543Smrg    }
1504706f2543Smrg
1505706f2543Smrg    /*
1506706f2543Smrg     **************************************************************************
1507706f2543Smrg     ** 3. Call the member routine, saving its result if necessary.
1508706f2543Smrg     **************************************************************************
1509706f2543Smrg     */
1510706f2543Smrg
1511706f2543Smrg    ret = (*pScreen->DestroyWindow)(pWin);
1512706f2543Smrg
1513706f2543Smrg    /*
1514706f2543Smrg     **************************************************************************
1515706f2543Smrg     ** 4. Rewrap the member routine, restoring the wrapper value first in case
1516706f2543Smrg     **    the wrapper (or something that it wrapped) change this value.
1517706f2543Smrg     **************************************************************************
1518706f2543Smrg     */
1519706f2543Smrg
1520706f2543Smrg    pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
1521706f2543Smrg    pScreen->DestroyWindow = DbeDestroyWindow;
1522706f2543Smrg
1523706f2543Smrg    /*
1524706f2543Smrg     **************************************************************************
1525706f2543Smrg     ** 5. Do any work necessary after the member routine has been called.
1526706f2543Smrg     **
1527706f2543Smrg     **    In this case we do not need to do anything.
1528706f2543Smrg     **************************************************************************
1529706f2543Smrg     */
1530706f2543Smrg
1531706f2543Smrg    return ret;
1532706f2543Smrg
1533706f2543Smrg} /* DbeDestroyWindow() */
1534706f2543Smrg
1535706f2543Smrg
1536706f2543Smrg/******************************************************************************
1537706f2543Smrg *
1538706f2543Smrg * DBE DIX Procedure: DbeExtensionInit
1539706f2543Smrg *
1540706f2543Smrg * Description:
1541706f2543Smrg *
1542706f2543Smrg *     Called from InitExtensions in main()
1543706f2543Smrg *
1544706f2543Smrg *****************************************************************************/
1545706f2543Smrg
1546706f2543Smrgvoid
1547706f2543SmrgDbeExtensionInit(void)
1548706f2543Smrg{
1549706f2543Smrg    ExtensionEntry	*extEntry;
1550706f2543Smrg    register int	i, j;
1551706f2543Smrg    ScreenPtr		pScreen = NULL;
1552706f2543Smrg    DbeScreenPrivPtr	pDbeScreenPriv;
1553706f2543Smrg    int			nStubbedScreens = 0;
1554706f2543Smrg    Bool		ddxInitSuccess;
1555706f2543Smrg
1556706f2543Smrg#ifdef PANORAMIX
1557706f2543Smrg    if(!noPanoramiXExtension) return;
1558706f2543Smrg#endif
1559706f2543Smrg
1560706f2543Smrg    /* Create the resource types. */
1561706f2543Smrg    dbeDrawableResType =
1562706f2543Smrg        CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
1563706f2543Smrg    if (!dbeDrawableResType)
1564706f2543Smrg	return;
1565706f2543Smrg    dbeDrawableResType |= RC_DRAWABLE;
1566706f2543Smrg
1567706f2543Smrg    dbeWindowPrivResType =
1568706f2543Smrg        CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
1569706f2543Smrg    if (!dbeWindowPrivResType)
1570706f2543Smrg	return;
1571706f2543Smrg
1572706f2543Smrg    if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0))
1573706f2543Smrg	return;
1574706f2543Smrg
1575706f2543Smrg    if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0))
1576706f2543Smrg	return;
1577706f2543Smrg
1578706f2543Smrg    for (i = 0; i < screenInfo.numScreens; i++)
1579706f2543Smrg    {
1580706f2543Smrg        /* For each screen, set up DBE screen privates and init DIX and DDX
1581706f2543Smrg         * interface.
1582706f2543Smrg         */
1583706f2543Smrg
1584706f2543Smrg	pScreen = screenInfo.screens[i];
1585706f2543Smrg
1586706f2543Smrg	if (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec))))
1587706f2543Smrg	{
1588706f2543Smrg            /* If we can not alloc a window or screen private,
1589706f2543Smrg             * then free any privates that we already alloc'ed and return
1590706f2543Smrg             */
1591706f2543Smrg
1592706f2543Smrg	    for (j = 0; j < i; j++)
1593706f2543Smrg	    {
1594706f2543Smrg		free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates,
1595706f2543Smrg				       dbeScreenPrivKey));
1596706f2543Smrg		dixSetPrivate(&screenInfo.screens[j]->devPrivates,
1597706f2543Smrg			      dbeScreenPrivKey, NULL);
1598706f2543Smrg	    }
1599706f2543Smrg	    return;
1600706f2543Smrg	}
1601706f2543Smrg
1602706f2543Smrg	dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv);
1603706f2543Smrg
1604706f2543Smrg        {
1605706f2543Smrg            /* We don't have DDX support for DBE anymore */
1606706f2543Smrg
1607706f2543Smrg#ifndef DISABLE_MI_DBE_BY_DEFAULT
1608706f2543Smrg            /* Setup DIX. */
1609706f2543Smrg            pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
1610706f2543Smrg
1611706f2543Smrg            /* Setup DDX. */
1612706f2543Smrg            ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
1613706f2543Smrg
1614706f2543Smrg            /* DDX DBE initialization may have the side affect of
1615706f2543Smrg             * reallocating pDbeScreenPriv, so we need to update it.
1616706f2543Smrg             */
1617706f2543Smrg            pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1618706f2543Smrg
1619706f2543Smrg            if (ddxInitSuccess)
1620706f2543Smrg            {
1621706f2543Smrg                /* Wrap DestroyWindow.  The DDX initialization function
1622706f2543Smrg                 * already wrapped PositionWindow for us.
1623706f2543Smrg                 */
1624706f2543Smrg
1625706f2543Smrg                pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
1626706f2543Smrg                pScreen->DestroyWindow        = DbeDestroyWindow;
1627706f2543Smrg            }
1628706f2543Smrg            else
1629706f2543Smrg            {
1630706f2543Smrg                /* DDX initialization failed.  Stub the screen. */
1631706f2543Smrg                DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
1632706f2543Smrg            }
1633706f2543Smrg#else
1634706f2543Smrg            DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
1635706f2543Smrg#endif
1636706f2543Smrg
1637706f2543Smrg        }
1638706f2543Smrg
1639706f2543Smrg    } /* for (i = 0; i < screenInfo.numScreens; i++) */
1640706f2543Smrg
1641706f2543Smrg
1642706f2543Smrg    if (nStubbedScreens == screenInfo.numScreens)
1643706f2543Smrg    {
1644706f2543Smrg	/* All screens stubbed.  Clean up and return. */
1645706f2543Smrg
1646706f2543Smrg        for (i = 0; i < screenInfo.numScreens; i++)
1647706f2543Smrg        {
1648706f2543Smrg		free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates,
1649706f2543Smrg				       dbeScreenPrivKey));
1650706f2543Smrg		dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
1651706f2543Smrg        }
1652706f2543Smrg        return;
1653706f2543Smrg    }
1654706f2543Smrg
1655706f2543Smrg
1656706f2543Smrg    /* Now add the extension. */
1657706f2543Smrg    extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
1658706f2543Smrg                            DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
1659706f2543Smrg                            DbeResetProc, StandardMinorOpcode);
1660706f2543Smrg
1661706f2543Smrg    dbeErrorBase = extEntry->errorBase;
1662706f2543Smrg    SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer);
1663706f2543Smrg    SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer);
1664706f2543Smrg
1665706f2543Smrg} /* DbeExtensionInit() */
1666706f2543Smrg
1667