Add penmount touchscreen configuration file
[profile/ivi/xorg-x11-server.git] / dbe / dbe.c
1 /******************************************************************************
2  * 
3  * Copyright (c) 1994, 1995  Hewlett-Packard Company
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  * 
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  * 
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  * 
24  * Except as contained in this notice, the name of the Hewlett-Packard
25  * Company shall not be used in advertising or otherwise to promote the
26  * sale, use or other dealings in this Software without prior written
27  * authorization from the Hewlett-Packard Company.
28  * 
29  *     DIX DBE code
30  *
31  *****************************************************************************/
32
33
34 /* INCLUDES */
35
36 #ifdef HAVE_DIX_CONFIG_H
37 #include <dix-config.h>
38 #endif
39
40 #include <string.h>
41 #if HAVE_STDINT_H
42 #include <stdint.h>
43 #elif !defined(UINT32_MAX)
44 #define UINT32_MAX 0xffffffffU
45 #endif
46
47 #include <X11/X.h>
48 #include <X11/Xproto.h>
49 #include "scrnintstr.h"
50 #include "extnsionst.h"
51 #include "gcstruct.h"
52 #include "dixstruct.h"
53 #define NEED_DBE_PROTOCOL
54 #include "dbestruct.h"
55 #include "midbe.h"
56 #include "xace.h"
57
58 /* GLOBALS */
59
60 /* These are globals for use by DDX */
61 DevPrivateKeyRec dbeScreenPrivKeyRec;
62 DevPrivateKeyRec dbeWindowPrivKeyRec;
63
64 /* These are globals for use by DDX */
65 RESTYPE dbeDrawableResType;
66 RESTYPE dbeWindowPrivResType;
67
68 /* Used to generate DBE's BadBuffer error. */
69 static int      dbeErrorBase;
70
71 /******************************************************************************
72  *
73  * DBE DIX Procedure: DbeStubScreen
74  *
75  * Description:
76  *
77  *     This is function stubs the function pointers in the given DBE screen
78  *     private and increments the number of stubbed screens.
79  *
80  *****************************************************************************/
81
82 static void
83 DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
84 {
85     /* Stub DIX. */
86     pDbeScreenPriv->SetupBackgroundPainter = NULL;
87
88     /* Do not unwrap PositionWindow nor DestroyWindow.  If the DDX
89      * initialization function failed, we assume that it did not wrap
90      * PositionWindow.  Also, DestroyWindow is only wrapped if the DDX
91      * initialization function succeeded.
92      */
93
94     /* Stub DDX. */
95     pDbeScreenPriv->GetVisualInfo       = NULL;
96     pDbeScreenPriv->AllocBackBufferName = NULL;
97     pDbeScreenPriv->SwapBuffers         = NULL;
98     pDbeScreenPriv->BeginIdiom          = NULL;
99     pDbeScreenPriv->EndIdiom            = NULL;
100     pDbeScreenPriv->WinPrivDelete       = NULL;
101     pDbeScreenPriv->ResetProc           = NULL;
102
103     (*nStubbedScreens)++;
104
105 } /* DbeStubScreen() */
106
107
108 \f
109 /******************************************************************************
110  *
111  * DBE DIX Procedure: ProcDbeGetVersion
112  *
113  * Description:
114  *
115  *     This function is for processing a DbeGetVersion request.
116  *     This request returns the major and minor version numbers of this
117  *     extension.
118  *
119  * Return Values:
120  *
121  *     Success
122  *
123  *****************************************************************************/
124
125 static int
126 ProcDbeGetVersion(ClientPtr client)
127 {
128     /* REQUEST(xDbeGetVersionReq); */
129     xDbeGetVersionReply rep;
130     register int        n;
131
132
133     REQUEST_SIZE_MATCH(xDbeGetVersionReq);
134
135     rep.type           = X_Reply;
136     rep.length         = 0;
137     rep.sequenceNumber = client->sequence;
138     rep.majorVersion   = DBE_MAJOR_VERSION;
139     rep.minorVersion   = DBE_MINOR_VERSION;
140
141     if (client->swapped)
142     {
143         swaps(&rep.sequenceNumber, n);
144     }
145
146     WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep);
147
148     return Success;
149
150 } /* ProcDbeGetVersion() */
151
152 \f
153 /******************************************************************************
154  *
155  * DBE DIX Procedure: ProcDbeAllocateBackBufferName
156  *
157  * Description:
158  *
159  *     This function is for processing a DbeAllocateBackBufferName request.
160  *     This request allocates a drawable ID used to refer to the back buffer
161  *     of a window.
162  *
163  * Return Values:
164  *
165  *     BadAlloc    - server can not allocate resources
166  *     BadIDChoice - id is out of range for client; id is already in use
167  *     BadMatch    - window is not an InputOutput window;
168  *                   visual of window is not on list returned by
169  *                   DBEGetVisualInfo; 
170  *     BadValue    - invalid swap action is specified
171  *     BadWindow   - window is not a valid window
172  *     Success
173  *
174  *****************************************************************************/
175
176 static int
177 ProcDbeAllocateBackBufferName(ClientPtr client)
178 {
179     REQUEST(xDbeAllocateBackBufferNameReq);
180     WindowPtr                   pWin;
181     DbeScreenPrivPtr            pDbeScreenPriv;
182     DbeWindowPrivPtr            pDbeWindowPriv;
183     XdbeScreenVisualInfo        scrVisInfo;
184     register int                i;
185     Bool                        visualMatched = FALSE;
186     xDbeSwapAction              swapAction;
187     VisualID                    visual;
188     int                         status;
189     int                         add_index;
190
191
192     REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
193
194     /* The window must be valid. */
195     status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
196     if (status != Success)
197         return status;
198
199     /* The window must be InputOutput. */
200     if (pWin->drawable.class != InputOutput)
201     {
202         return BadMatch;
203     }
204
205     /* The swap action must be valid. */
206     swapAction = stuff->swapAction;     /* use local var for performance. */
207     if ((swapAction != XdbeUndefined ) &&
208         (swapAction != XdbeBackground) &&
209         (swapAction != XdbeUntouched ) &&
210         (swapAction != XdbeCopied    ))
211     {
212         return BadValue;
213     }
214
215     /* The id must be in range and not already in use. */
216     LEGAL_NEW_RESOURCE(stuff->buffer, client);
217
218     /* The visual of the window must be in the list returned by
219      * GetVisualInfo.
220      */
221     pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
222     if (!pDbeScreenPriv->GetVisualInfo)
223         return BadMatch; /* screen doesn't support double buffering */
224
225     if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
226     {
227         /* GetVisualInfo() failed to allocate visual info data. */
228         return BadAlloc;
229     }
230
231     /* See if the window's visual is on the list. */
232     visual = wVisual(pWin);
233     for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++)
234     {
235         if (scrVisInfo.visinfo[i].visual == visual)
236         {
237             visualMatched = TRUE;
238         }
239     }
240
241     /* Free what was allocated by the GetVisualInfo() call above. */
242     free(scrVisInfo.visinfo);
243
244     if (!visualMatched)
245     {
246         return BadMatch;
247     }
248
249     if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
250     {
251         /* There is no buffer associated with the window.
252          * Allocate a window priv.
253          */
254
255         pDbeWindowPriv = dixAllocateObjectWithPrivates(DbeWindowPrivRec, PRIVATE_DBE_WINDOW);
256         if (!pDbeWindowPriv)
257             return BadAlloc;
258
259         /* Fill out window priv information. */
260         pDbeWindowPriv->pWindow      = pWin;
261         pDbeWindowPriv->width        = pWin->drawable.width;
262         pDbeWindowPriv->height       = pWin->drawable.height;
263         pDbeWindowPriv->x            = pWin->drawable.x;
264         pDbeWindowPriv->y            = pWin->drawable.y;
265         pDbeWindowPriv->nBufferIDs   = 0;
266
267         /* Set the buffer ID array pointer to the initial (static) array). */
268         pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
269
270         /* Initialize the buffer ID list. */ 
271         pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
272         pDbeWindowPriv->IDs[0] = stuff->buffer;
273
274         add_index = 0;
275         for (i = 0; i < DBE_INIT_MAX_IDS; i++)
276         {
277             pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
278         }
279
280         /* Actually connect the window priv to the window. */
281         dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
282
283     } /* if -- There is no buffer associated with the window. */
284
285     else
286     {
287         /* A buffer is already associated with the window.
288          * Add the new buffer ID to the array, reallocating the array memory
289          * if necessary.
290          */
291
292         /* Determine if there is a free element in the ID array. */
293         for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++)
294         {
295             if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT)
296             {
297                 /* There is still room in the ID array. */
298                 break;
299             }
300         }
301  
302         if (i == pDbeWindowPriv->maxAvailableIDs)
303         {
304             /* No more room in the ID array -- reallocate another array. */
305             XID *pIDs;
306
307             /* Setup an array pointer for the realloc operation below. */
308             if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
309             {
310                 /* We will malloc a new array. */
311                 pIDs = NULL;
312             }
313             else
314             {
315                 /* We will realloc a new array. */
316                 pIDs = pDbeWindowPriv->IDs;
317             }
318
319             /* malloc/realloc a new array and initialize all elements to 0. */
320             pDbeWindowPriv->IDs = (XID *)realloc(pIDs,
321                 (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID));
322             if (!pDbeWindowPriv->IDs)
323             {
324                 return BadAlloc;
325             }
326             memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
327                    (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
328                     pDbeWindowPriv->nBufferIDs) * sizeof(XID));
329
330             if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
331             {
332                 /* We just went from using the initial (static) array to a
333                  * newly allocated array.  Copy the IDs from the initial array
334                  * to the new array.
335                  */
336                 memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
337                        DBE_INIT_MAX_IDS * sizeof(XID));
338             }
339
340             pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
341         }
342
343         add_index = i;
344
345     } /* else -- A buffer is already associated with the window. */
346
347
348     /* Call the DDX routine to allocate the back buffer. */
349     status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
350                                                     stuff->swapAction);
351
352     if (status == Success)
353     {
354         pDbeWindowPriv->IDs[add_index] = stuff->buffer;
355         if (!AddResource(stuff->buffer, dbeWindowPrivResType,
356                          (pointer)pDbeWindowPriv))
357         {
358             pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
359
360             if (pDbeWindowPriv->nBufferIDs == 0) {
361                 status = BadAlloc;
362                 goto out_free;
363             }
364         }
365     } else {
366         /* The DDX buffer allocation routine failed for the first buffer of
367          * this window.
368          */
369         if (pDbeWindowPriv->nBufferIDs == 0) {
370             goto out_free;
371         }
372     }
373
374     /* Increment the number of buffers (XIDs) associated with this window. */
375     pDbeWindowPriv->nBufferIDs++;
376
377     /* Set swap action on all calls. */
378     pDbeWindowPriv->swapAction = stuff->swapAction;
379
380     return status;
381
382 out_free:
383     dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
384     free(pDbeWindowPriv);
385     return status;
386
387 } /* ProcDbeAllocateBackBufferName() */
388
389 \f
390 /******************************************************************************
391  *
392  * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
393  *
394  * Description:
395  *
396  *     This function is for processing a DbeDeallocateBackBufferName request.
397  *     This request frees a drawable ID that was obtained by a
398  *     DbeAllocateBackBufferName request.
399  *
400  * Return Values:
401  *
402  *     BadBuffer - buffer to deallocate is not associated with a window
403  *     Success
404  *
405  *****************************************************************************/
406
407 static int
408 ProcDbeDeallocateBackBufferName(ClientPtr client)
409 {
410     REQUEST(xDbeDeallocateBackBufferNameReq);
411     DbeWindowPrivPtr    pDbeWindowPriv;
412     int                 rc, i;
413     pointer val;
414
415
416     REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
417
418     /* Buffer name must be valid */
419     rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
420                                  dbeWindowPrivResType, client,
421                                  DixDestroyAccess);
422     if (rc != Success)
423         return rc;
424
425     rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
426                                  client, DixDestroyAccess);
427     if (rc != Success)
428         return rc;
429
430     /* Make sure that the id is valid for the window.
431      * This is paranoid code since we already looked up the ID by type
432      * above.
433      */
434
435     for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
436     {
437         /* Loop through the ID list to find the ID. */
438         if (pDbeWindowPriv->IDs[i] == stuff->buffer)
439         {
440             break;
441         }
442     }
443
444     if (i == pDbeWindowPriv->nBufferIDs)
445     {
446         /* We did not find the ID in the ID list. */
447         client->errorValue = stuff->buffer;
448         return dbeErrorBase + DbeBadBuffer;
449     }
450
451     FreeResource(stuff->buffer, RT_NONE);
452
453     return Success;
454
455 } /* ProcDbeDeallocateBackBufferName() */
456
457 \f
458 /******************************************************************************
459  *
460  * DBE DIX Procedure: ProcDbeSwapBuffers
461  *
462  * Description:
463  *
464  *     This function is for processing a DbeSwapBuffers request.
465  *     This request swaps the buffers for all windows listed, applying the
466  *     appropriate swap action for each window.
467  *
468  * Return Values:
469  *
470  *     BadAlloc  - local allocation failed; this return value is not defined
471  *                 by the protocol
472  *     BadMatch  - a window in request is not double-buffered; a window in
473  *                 request is listed more than once
474  *     BadValue  - invalid swap action is specified; no swap action is
475  *                 specified
476  *     BadWindow - a window in request is not valid
477  *     Success
478  *
479  *****************************************************************************/
480
481 static int
482 ProcDbeSwapBuffers(ClientPtr client)
483 {
484     REQUEST(xDbeSwapBuffersReq);
485     WindowPtr           pWin;
486     DbeScreenPrivPtr    pDbeScreenPriv;
487     DbeSwapInfoPtr      swapInfo;
488     xDbeSwapInfo        *dbeSwapInfo;
489     int                 error;
490     register int        i, j;
491     int                 nStuff;
492
493
494     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
495     nStuff = stuff->n;  /* use local variable for performance. */
496
497     if (nStuff == 0)
498     {
499         return Success;
500     }
501
502     if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
503             return BadAlloc;
504
505     /* Get to the swap info appended to the end of the request. */
506     dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
507
508     /* Allocate array to record swap information. */ 
509     swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec));
510     if (swapInfo == NULL)
511     {
512         return BadAlloc;
513     }
514
515
516     for (i = 0; i < nStuff; i++)
517     {
518         /* Check all windows to swap. */
519
520         /* Each window must be a valid window - BadWindow. */
521         error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
522                                 DixWriteAccess);
523         if (error != Success) {
524             free(swapInfo);
525             return error;
526         }
527
528         /* Each window must be double-buffered - BadMatch. */
529         if (DBE_WINDOW_PRIV(pWin) == NULL)
530         {
531             free(swapInfo);
532             return BadMatch;
533         }
534
535         /* Each window must only be specified once - BadMatch. */
536         for (j = i + 1; j < nStuff; j++)
537         {
538             if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
539             {
540                 free(swapInfo);
541                 return BadMatch;
542             }
543         }
544
545         /* Each swap action must be valid - BadValue. */
546         if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) &&
547             (dbeSwapInfo[i].swapAction != XdbeBackground) &&
548             (dbeSwapInfo[i].swapAction != XdbeUntouched ) &&
549             (dbeSwapInfo[i].swapAction != XdbeCopied    ))
550         {
551             free(swapInfo);
552             return BadValue;
553         }
554
555         /* Everything checks out OK.  Fill in the swap info array. */
556         swapInfo[i].pWindow    = pWin;     
557         swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;     
558
559     } /* for (i = 0; i < nStuff; i++) */
560
561
562     /* Call the DDX routine to perform the swap(s).  The DDX routine should
563      * scan the swap list (swap info), swap any buffers that it knows how to
564      * handle, delete them from the list, and update nStuff to indicate how
565      * many windows it did not handle.
566      *
567      * This scheme allows a range of sophistication in the DDX SwapBuffers()
568      * implementation.  Naive implementations could just swap the first buffer
569      * in the list, move the last buffer to the front, decrement nStuff, and
570      * return.  The next level of sophistication could be to scan the whole
571      * list for windows on the same screen.  Up another level, the DDX routine
572      * could deal with cross-screen synchronization.
573      */
574
575     while (nStuff > 0)
576     {
577         pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
578         error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo);
579         if (error != Success)
580         {
581             free(swapInfo);
582             return error;
583         }
584     }
585     
586     free(swapInfo);
587     return Success;
588
589 } /* ProcDbeSwapBuffers() */
590
591 \f
592 /******************************************************************************
593  *
594  * DBE DIX Procedure: ProcDbeBeginIdiom
595  *
596  * Description:
597  *
598  *     This function is for processing a DbeBeginIdiom request.
599  *     This request informs the server that a complex swap will immediately
600  *     follow this request.
601  *
602  * Return Values:
603  *
604  *     Success
605  *
606  *****************************************************************************/
607
608 static int
609 ProcDbeBeginIdiom(ClientPtr client)
610 {
611     /* REQUEST(xDbeBeginIdiomReq); */
612     DbeScreenPrivPtr    pDbeScreenPriv;
613     register int        i;
614
615
616     REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
617
618     for (i = 0; i < screenInfo.numScreens; i++)
619     {
620         pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
621
622         /* Call the DDX begin idiom procedure if there is one. */
623         if (pDbeScreenPriv->BeginIdiom)
624         {
625            (*pDbeScreenPriv->BeginIdiom)(client);
626         }
627     }
628
629     return Success;
630
631 } /* ProcDbeBeginIdiom() */
632
633 \f
634 /******************************************************************************
635  *
636  * DBE DIX Procedure: ProcDbeGetVisualInfo
637  *
638  * Description:
639  *
640  *     This function is for processing a ProcDbeGetVisualInfo request.
641  *     This request returns information about which visuals support
642  *     double buffering.
643  *
644  * Return Values:
645  *
646  *     BadDrawable - value in screen specifiers is not a valid drawable
647  *     Success
648  *
649  *****************************************************************************/
650
651 static int
652 ProcDbeGetVisualInfo(ClientPtr client)
653 {
654     REQUEST(xDbeGetVisualInfoReq);
655     DbeScreenPrivPtr            pDbeScreenPriv;
656     xDbeGetVisualInfoReply      rep;
657     Drawable                    *drawables;
658     DrawablePtr                 *pDrawables = NULL;
659     register int                i, j, n, rc;
660     register int                count;  /* number of visual infos in reply */
661     register int                length; /* length of reply */
662     ScreenPtr                   pScreen;
663     XdbeScreenVisualInfo        *pScrVisInfo;
664
665
666     REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
667
668     if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
669             return BadAlloc;
670     /* Make sure any specified drawables are valid. */
671     if (stuff->n != 0)
672     {
673         if (!(pDrawables = (DrawablePtr *)malloc(stuff->n *
674                                                  sizeof(DrawablePtr))))
675         {
676             return BadAlloc;
677         }
678
679         drawables = (Drawable *)&stuff[1];
680
681         for (i = 0; i < stuff->n; i++)
682         {
683             rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0,
684                                    DixGetAttrAccess);
685             if (rc != Success) {
686                 free(pDrawables);
687                 return rc;
688             }
689         }
690     }
691
692     count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
693     if (!(pScrVisInfo = (XdbeScreenVisualInfo *)malloc(count *
694                         sizeof(XdbeScreenVisualInfo))))
695     {
696         free(pDrawables);
697
698         return BadAlloc;
699     }
700
701     length = 0;
702
703     for (i = 0; i < count; i++)
704     {
705         pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
706                                     pDrawables[i]->pScreen;
707         pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
708
709         rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
710         if ((rc != Success) ||
711             !(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
712         {
713             /* We failed to alloc pScrVisInfo[i].visinfo. */
714
715             /* Free visinfos that we allocated for previous screen infos.*/
716             for (j = 0; j < i; j++)
717             {
718                 free(pScrVisInfo[j].visinfo);
719             }
720
721             /* Free pDrawables if we needed to allocate it above. */
722             free(pDrawables);
723
724             return (rc == Success) ? BadAlloc : rc;
725         }
726
727         /* Account for n, number of xDbeVisInfo items in list. */
728         length += sizeof(CARD32);
729
730         /* Account for n xDbeVisInfo items */
731         length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
732     }
733
734     rep.type           = X_Reply;
735     rep.sequenceNumber = client->sequence;
736     rep.length         = bytes_to_int32(length);
737     rep.m              = count;
738
739     if (client->swapped)
740     {
741         swaps(&rep.sequenceNumber, n);
742         swapl(&rep.length, n);
743         swapl(&rep.m, n);
744     }
745
746     /* Send off reply. */
747     WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep);
748
749     for (i = 0; i < count; i++)
750     {
751         CARD32  data32;
752
753         /* For each screen in the reply, send off the visual info */
754
755         /* Send off number of visuals. */
756         data32 = (CARD32)pScrVisInfo[i].count;
757
758         if (client->swapped)
759         {
760             swapl(&data32, n);
761         }
762
763         WriteToClient(client, sizeof(CARD32), (char *)&data32);
764
765         /* Now send off visual info items. */
766         for (j = 0; j < pScrVisInfo[i].count; j++)
767         {
768             xDbeVisInfo         visInfo;
769
770             /* Copy the data in the client data structure to a protocol
771              * data structure.  We will send data to the client from the
772              * protocol data structure.
773              */
774
775             visInfo.visualID  = (CARD32)pScrVisInfo[i].visinfo[j].visual;
776             visInfo.depth     = (CARD8) pScrVisInfo[i].visinfo[j].depth;
777             visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
778
779             if (client->swapped)
780             {
781                 swapl(&visInfo.visualID, n);
782
783                 /* We do not need to swap depth and perfLevel since they are
784                  * already 1 byte quantities.
785                  */
786             }
787
788             /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
789             WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID);
790         }
791     }
792
793     /* Clean up memory. */
794     for (i = 0; i < count; i++)
795     {
796         free(pScrVisInfo[i].visinfo);
797     }
798     free(pScrVisInfo);
799
800     free(pDrawables);
801
802     return Success;
803
804 } /* ProcDbeGetVisualInfo() */
805
806 \f
807 /******************************************************************************
808  *
809  * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
810  *
811  * Description:
812  *
813  *     This function is for processing a ProcDbeGetbackBufferAttributes
814  *     request.  This request returns information about a back buffer.
815  *
816  * Return Values:
817  *
818  *     Success
819  *
820  *****************************************************************************/
821
822 static int
823 ProcDbeGetBackBufferAttributes(ClientPtr client)
824 {
825     REQUEST(xDbeGetBackBufferAttributesReq);
826     xDbeGetBackBufferAttributesReply    rep;
827     DbeWindowPrivPtr                    pDbeWindowPriv;
828     int                                 rc, n;
829
830
831     REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
832
833     rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
834                                  dbeWindowPrivResType, client,
835                                  DixGetAttrAccess);
836     if (rc == Success)
837     {
838         rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
839     }
840     else
841     {
842         rep.attributes = None;
843     }
844         
845     rep.type           = X_Reply;
846     rep.sequenceNumber = client->sequence;
847     rep.length         = 0;
848     
849     if (client->swapped)
850     {
851         swaps(&rep.sequenceNumber, n);
852         swapl(&rep.length, n);
853         swapl(&rep.attributes, n);
854     }
855
856     WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
857                   (char *)&rep);
858     return Success;
859
860 } /* ProcDbeGetbackBufferAttributes() */
861
862 \f
863 /******************************************************************************
864  *
865  * DBE DIX Procedure: ProcDbeDispatch
866  *
867  * Description:
868  *
869  *     This function dispatches DBE requests.
870  *
871  *****************************************************************************/
872
873 static int
874 ProcDbeDispatch(ClientPtr client)
875 {
876     REQUEST(xReq);
877
878
879     switch (stuff->data)
880     {
881         case X_DbeGetVersion:
882             return(ProcDbeGetVersion(client));
883
884         case X_DbeAllocateBackBufferName:
885             return(ProcDbeAllocateBackBufferName(client));
886
887         case X_DbeDeallocateBackBufferName:
888             return(ProcDbeDeallocateBackBufferName(client));
889
890         case X_DbeSwapBuffers:
891             return(ProcDbeSwapBuffers(client));
892
893         case X_DbeBeginIdiom:
894             return(ProcDbeBeginIdiom(client));
895
896         case X_DbeEndIdiom:
897             return Success;
898
899         case X_DbeGetVisualInfo:
900             return(ProcDbeGetVisualInfo(client));
901
902         case X_DbeGetBackBufferAttributes:
903             return(ProcDbeGetBackBufferAttributes(client));
904
905         default:
906             return BadRequest;
907     }
908
909 } /* ProcDbeDispatch() */
910
911 \f
912 /******************************************************************************
913  *
914  * DBE DIX Procedure: SProcDbeGetVersion
915  *
916  * Description:
917  *
918  *     This function is for processing a DbeGetVersion request on a swapped
919  *     server.  This request returns the major and minor version numbers of
920  *     this extension.
921  *
922  * Return Values:
923  *
924  *     Success
925  *
926  *****************************************************************************/
927
928 static int
929 SProcDbeGetVersion(ClientPtr client)
930 {
931     REQUEST(xDbeGetVersionReq);
932     register int        n;
933
934
935     swaps(&stuff->length, n);
936     return(ProcDbeGetVersion(client));
937
938 } /* SProcDbeGetVersion() */
939
940 \f
941 /******************************************************************************
942  *
943  * DBE DIX Procedure: SProcDbeAllocateBackBufferName
944  *
945  * Description:
946  *
947  *     This function is for processing a DbeAllocateBackBufferName request on
948  *     a swapped server.  This request allocates a drawable ID used to refer
949  *     to the back buffer of a window.
950  *
951  * Return Values:
952  *
953  *     BadAlloc    - server can not allocate resources
954  *     BadIDChoice - id is out of range for client; id is already in use
955  *     BadMatch    - window is not an InputOutput window;
956  *                   visual of window is not on list returned by
957  *                   DBEGetVisualInfo; 
958  *     BadValue    - invalid swap action is specified
959  *     BadWindow   - window is not a valid window
960  *     Success
961  *
962  *****************************************************************************/
963
964 static int
965 SProcDbeAllocateBackBufferName(ClientPtr client)
966 {
967     REQUEST(xDbeAllocateBackBufferNameReq);
968     register int        n;
969
970     swaps(&stuff->length, n);
971     REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
972
973     swapl(&stuff->window, n);
974     swapl(&stuff->buffer, n);
975     /* stuff->swapAction is a byte.  We do not need to swap this field. */
976
977     return(ProcDbeAllocateBackBufferName(client));
978
979 } /* SProcDbeAllocateBackBufferName() */
980
981 \f
982 /******************************************************************************
983  *
984  * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
985  *
986  * Description:
987  *
988  *     This function is for processing a DbeDeallocateBackBufferName request
989  *     on a swapped server.  This request frees a drawable ID that was
990  *     obtained by a DbeAllocateBackBufferName request.
991  *
992  * Return Values:
993  *
994  *     BadBuffer - buffer to deallocate is not associated with a window
995  *     Success
996  *
997  *****************************************************************************/
998
999 static int
1000 SProcDbeDeallocateBackBufferName(ClientPtr client)
1001 {
1002     REQUEST (xDbeDeallocateBackBufferNameReq);
1003     register int        n;
1004
1005
1006     swaps(&stuff->length, n);
1007     REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
1008
1009     swapl(&stuff->buffer, n);
1010
1011     return(ProcDbeDeallocateBackBufferName(client));
1012
1013 } /* SProcDbeDeallocateBackBufferName() */
1014
1015 \f
1016 /******************************************************************************
1017  *
1018  * DBE DIX Procedure: SProcDbeSwapBuffers
1019  *
1020  * Description:
1021  *
1022  *     This function is for processing a DbeSwapBuffers request on a swapped
1023  *     server.  This request swaps the buffers for all windows listed,
1024  *     applying the appropriate swap action for each window.
1025  *
1026  * Return Values:
1027  *
1028  *     BadMatch  - a window in request is not double-buffered; a window in
1029  *                 request is listed more than once; all windows in request do
1030  *                 not have the same root
1031  *     BadValue  - invalid swap action is specified
1032  *     BadWindow - a window in request is not valid
1033  *     Success
1034  *
1035  *****************************************************************************/
1036
1037 static int
1038 SProcDbeSwapBuffers(ClientPtr client)
1039 {
1040     REQUEST(xDbeSwapBuffersReq);
1041     register int        i, n;
1042     xDbeSwapInfo        *pSwapInfo;
1043
1044
1045     swaps(&stuff->length, n);
1046     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
1047
1048     swapl(&stuff->n, n);
1049
1050     if (stuff->n != 0)
1051     { 
1052         pSwapInfo = (xDbeSwapInfo *)stuff+1;
1053
1054         /* The swap info following the fix part of this request is a window(32)
1055          * followed by a 1 byte swap action and then 3 pad bytes.  We only need
1056          * to swap the window information.
1057          */
1058         for (i = 0; i < stuff->n; i++)
1059         {
1060             swapl(&pSwapInfo->window, n);
1061         }
1062     }
1063
1064     return(ProcDbeSwapBuffers(client));
1065
1066 } /* SProcDbeSwapBuffers() */
1067
1068 \f
1069 /******************************************************************************
1070  *
1071  * DBE DIX Procedure: SProcDbeBeginIdiom
1072  *
1073  * Description:
1074  *
1075  *     This function is for processing a DbeBeginIdiom request on a swapped
1076  *     server.  This request informs the server that a complex swap will
1077  *     immediately follow this request.
1078  *
1079  * Return Values:
1080  *
1081  *     Success
1082  *
1083  *****************************************************************************/
1084
1085 static int
1086 SProcDbeBeginIdiom(ClientPtr client)
1087 {
1088     REQUEST(xDbeBeginIdiomReq);
1089     register int        n;
1090
1091     swaps(&stuff->length, n);
1092     return(ProcDbeBeginIdiom(client));
1093
1094 } /* SProcDbeBeginIdiom() */
1095
1096 \f
1097 /******************************************************************************
1098  *
1099  * DBE DIX Procedure: SProcDbeGetVisualInfo
1100  *
1101  * Description:
1102  *
1103  *     This function is for processing a ProcDbeGetVisualInfo request on a
1104  *     swapped server.  This request returns information about which visuals
1105  *     support double buffering.
1106  *
1107  * Return Values:
1108  *
1109  *     BadDrawable - value in screen specifiers is not a valid drawable
1110  *     Success
1111  *
1112  *****************************************************************************/
1113
1114 static int
1115 SProcDbeGetVisualInfo(ClientPtr client)
1116 {
1117     REQUEST(xDbeGetVisualInfoReq);
1118     register int        n;
1119
1120
1121     swaps(&stuff->length, n);
1122     REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
1123
1124     swapl(&stuff->n, n);
1125     SwapRestL(stuff);
1126
1127     return(ProcDbeGetVisualInfo(client));
1128
1129 } /* SProcDbeGetVisualInfo() */
1130
1131 \f
1132 /******************************************************************************
1133  *
1134  * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
1135  *
1136  * Description:
1137  *
1138  *     This function is for processing a ProcDbeGetbackBufferAttributes
1139  *     request on a swapped server.  This request returns information about a
1140  *     back buffer.
1141  *
1142  * Return Values:
1143  *
1144  *     Success
1145  *
1146  *****************************************************************************/
1147
1148 static int
1149 SProcDbeGetBackBufferAttributes(ClientPtr client)
1150 {
1151     REQUEST (xDbeGetBackBufferAttributesReq);
1152     register int        n;
1153
1154     swaps(&stuff->length, n);
1155     REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
1156
1157     swapl(&stuff->buffer, n);
1158
1159     return(ProcDbeGetBackBufferAttributes(client));
1160
1161 } /* SProcDbeGetBackBufferAttributes() */
1162
1163 \f
1164 /******************************************************************************
1165  *
1166  * DBE DIX Procedure: SProcDbeDispatch
1167  *
1168  * Description:
1169  *
1170  *     This function dispatches DBE requests on a swapped server.
1171  *
1172  *****************************************************************************/
1173
1174 static int
1175 SProcDbeDispatch(ClientPtr client)
1176 {
1177     REQUEST(xReq);
1178
1179
1180     switch (stuff->data)
1181     {
1182         case X_DbeGetVersion:
1183             return(SProcDbeGetVersion(client));
1184
1185         case X_DbeAllocateBackBufferName:
1186             return(SProcDbeAllocateBackBufferName(client));
1187
1188         case X_DbeDeallocateBackBufferName:
1189             return(SProcDbeDeallocateBackBufferName(client));
1190
1191         case X_DbeSwapBuffers:
1192             return(SProcDbeSwapBuffers(client));
1193
1194         case X_DbeBeginIdiom:
1195             return(SProcDbeBeginIdiom(client));
1196
1197         case X_DbeEndIdiom:
1198             return Success;
1199
1200         case X_DbeGetVisualInfo:
1201             return(SProcDbeGetVisualInfo(client));
1202
1203         case X_DbeGetBackBufferAttributes:
1204             return(SProcDbeGetBackBufferAttributes(client));
1205
1206         default:
1207             return BadRequest;
1208     }
1209
1210 } /* SProcDbeDispatch() */
1211
1212 \f
1213 /******************************************************************************
1214  *
1215  * DBE DIX Procedure: DbeSetupBackgroundPainter
1216  *
1217  * Description:
1218  *
1219  *     This function sets up pGC to clear pixmaps.
1220  *
1221  * Return Values:
1222  *
1223  *     TRUE  - setup was successful
1224  *     FALSE - the window's background state is NONE
1225  * 
1226  *****************************************************************************/
1227
1228 static Bool
1229 DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
1230 {
1231     ChangeGCVal gcvalues[4];
1232     int         ts_x_origin, ts_y_origin;
1233     PixUnion    background;
1234     int         backgroundState;
1235     Mask        gcmask;
1236
1237
1238     /* First take care of any ParentRelative stuff by altering the
1239      * tile/stipple origin to match the coordinates of the upper-left
1240      * corner of the first ancestor without a ParentRelative background.
1241      * This coordinate is, of course, negative.
1242      */
1243     ts_x_origin = ts_y_origin = 0;
1244     while (pWin->backgroundState == ParentRelative)
1245     {
1246         ts_x_origin -= pWin->origin.x;
1247         ts_y_origin -= pWin->origin.y;
1248
1249         pWin = pWin->parent;
1250     }
1251     backgroundState = pWin->backgroundState;
1252     background      = pWin->background;
1253
1254     switch (backgroundState)
1255     {
1256         case BackgroundPixel:
1257             gcvalues[0].val = background.pixel;
1258             gcvalues[1].val = FillSolid;
1259             gcmask = GCForeground|GCFillStyle;
1260             break;
1261
1262         case BackgroundPixmap:
1263             gcvalues[0].val = FillTiled;
1264             gcvalues[1].ptr = background.pixmap;
1265             gcvalues[2].val = ts_x_origin;
1266             gcvalues[3].val = ts_y_origin;
1267             gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
1268             break;
1269
1270         default:
1271             /* pWin->backgroundState == None */
1272             return FALSE;
1273     }
1274
1275     return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
1276 } /* DbeSetupBackgroundPainter() */
1277
1278 \f
1279 /******************************************************************************
1280  *
1281  * DBE DIX Procedure: DbeDrawableDelete
1282  *
1283  * Description:
1284  *
1285  *     This is the resource delete function for dbeDrawableResType.
1286  *     It is registered when the drawable resource type is created in
1287  *     DbeExtensionInit().
1288  *
1289  *     To make resource deletion simple, we do not do anything in this function
1290  *     and leave all resource deleteion to DbeWindowPrivDelete(), which will
1291  *     eventually be called or already has been called.  Deletion functions are
1292  *     not guaranteed to be called in any particular order.
1293  *
1294  *****************************************************************************/
1295 static int
1296 DbeDrawableDelete(pointer pDrawable, XID id)
1297 {
1298     return Success;
1299
1300 } /* DbeDrawableDelete() */
1301
1302 \f
1303 /******************************************************************************
1304  *
1305  * DBE DIX Procedure: DbeWindowPrivDelete
1306  *
1307  * Description:
1308  *
1309  *     This is the resource delete function for dbeWindowPrivResType.
1310  *     It is registered when the drawable resource type is created in
1311  *     DbeExtensionInit().
1312  *
1313  *****************************************************************************/
1314 static int
1315 DbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
1316 {
1317     DbeScreenPrivPtr    pDbeScreenPriv;
1318     DbeWindowPrivPtr    pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv;
1319     int                 i;
1320
1321
1322     /*
1323      **************************************************************************
1324      ** Remove the buffer ID from the ID array.
1325      **************************************************************************
1326      */
1327
1328     /* Find the ID in the ID array. */
1329     i = 0;
1330     while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id))
1331     {
1332         i++;
1333     }
1334
1335     if (i == pDbeWindowPriv->nBufferIDs)
1336     {
1337         /* We did not find the ID in the array.  We should never get here. */
1338         return BadValue;
1339     }
1340
1341     /* Remove the ID from the array. */
1342
1343     if (i < (pDbeWindowPriv->nBufferIDs - 1))
1344     {
1345         /* Compress the buffer ID array, overwriting the ID in the process. */
1346         memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1],
1347             (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
1348     }
1349     else
1350     {
1351         /* We are removing the last ID in the array, in which case, the
1352          * assignement below is all that we need to do.
1353          */
1354     }
1355     pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
1356
1357     pDbeWindowPriv->nBufferIDs--;
1358
1359     /* If an extended array was allocated, then check to see if the remaining
1360      * buffer IDs will fit in the static array.
1361      */
1362
1363     if ((pDbeWindowPriv->maxAvailableIDs >  DBE_INIT_MAX_IDS) &&
1364         (pDbeWindowPriv->nBufferIDs      == DBE_INIT_MAX_IDS))
1365     {
1366         /* Copy the IDs back into the static array. */
1367         memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
1368                DBE_INIT_MAX_IDS * sizeof(XID));
1369
1370         /* Free the extended array; use the static array. */
1371         free(pDbeWindowPriv->IDs);
1372         pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
1373         pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
1374     }
1375
1376
1377     /*
1378      **************************************************************************
1379      ** Perform DDX level tasks.
1380      **************************************************************************
1381      */
1382
1383     pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(
1384                          (DbeWindowPrivPtr)pDbeWindowPriv);
1385     (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id);
1386
1387
1388     /*
1389      **************************************************************************
1390      ** Perform miscellaneous tasks if this is the last buffer associated
1391      ** with the window.
1392      **************************************************************************
1393      */
1394
1395     if (pDbeWindowPriv->nBufferIDs == 0)
1396     {
1397         /* Reset the DBE window priv pointer. */
1398         dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
1399                       NULL);
1400
1401         /* We are done with the window priv. */
1402         dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW);
1403     }
1404
1405     return Success;
1406
1407 } /* DbeWindowPrivDelete() */
1408
1409 \f
1410 /******************************************************************************
1411  *
1412  * DBE DIX Procedure: DbeResetProc
1413  *
1414  * Description:
1415  *
1416  *     This routine is called at the end of every server generation.
1417  *     It deallocates any memory reserved for the extension and performs any
1418  *     other tasks related to shutting down the extension.
1419  *
1420  *****************************************************************************/
1421 static void
1422 DbeResetProc(ExtensionEntry *extEntry)
1423 {
1424     int                 i;
1425     ScreenPtr           pScreen;
1426     DbeScreenPrivPtr    pDbeScreenPriv;
1427     
1428     for (i = 0; i < screenInfo.numScreens; i++)
1429     {
1430         pScreen = screenInfo.screens[i];
1431         pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1432
1433         if (pDbeScreenPriv)
1434         {
1435             /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/
1436             pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1437
1438             if (pDbeScreenPriv->ResetProc)
1439                 (*pDbeScreenPriv->ResetProc)(pScreen);
1440
1441             free(pDbeScreenPriv);
1442         }
1443     }
1444 } /* DbeResetProc() */
1445
1446 \f
1447 /******************************************************************************
1448  *
1449  * DBE DIX Procedure: DbeDestroyWindow
1450  *
1451  * Description:
1452  *
1453  *     This is the wrapper for pScreen->DestroyWindow.
1454  *     This function frees buffer resources for a window before it is
1455  *     destroyed.
1456  *
1457  *****************************************************************************/
1458
1459 static Bool
1460 DbeDestroyWindow(WindowPtr pWin)
1461 {
1462     DbeScreenPrivPtr    pDbeScreenPriv;
1463     DbeWindowPrivPtr    pDbeWindowPriv;
1464     ScreenPtr           pScreen;
1465     Bool                ret;
1466
1467
1468     /*
1469      **************************************************************************
1470      ** 1. Unwrap the member routine.
1471      **************************************************************************
1472      */
1473
1474     pScreen                = pWin->drawable.pScreen;
1475     pDbeScreenPriv         = DBE_SCREEN_PRIV(pScreen);
1476     pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1477
1478     /*
1479      **************************************************************************
1480      ** 2. Do any work necessary before the member routine is called.
1481      **
1482      **    Call the window priv delete function for all buffer IDs associated
1483      **    with this window.
1484      **************************************************************************
1485      */
1486
1487     if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
1488     {
1489         while (pDbeWindowPriv)
1490         {
1491             /* *DbeWinPrivDelete() will free the window private and set it to
1492              * NULL if there are no more buffer IDs associated with this
1493              * window.
1494              */
1495             FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
1496             pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
1497         }
1498     }
1499
1500     /*
1501      **************************************************************************
1502      ** 3. Call the member routine, saving its result if necessary.
1503      **************************************************************************
1504      */
1505
1506     ret = (*pScreen->DestroyWindow)(pWin);
1507
1508     /*
1509      **************************************************************************
1510      ** 4. Rewrap the member routine, restoring the wrapper value first in case
1511      **    the wrapper (or something that it wrapped) change this value.
1512      **************************************************************************
1513      */
1514
1515     pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
1516     pScreen->DestroyWindow = DbeDestroyWindow;
1517
1518     /*
1519      **************************************************************************
1520      ** 5. Do any work necessary after the member routine has been called.
1521      **
1522      **    In this case we do not need to do anything.
1523      **************************************************************************
1524      */
1525
1526     return ret;
1527
1528 } /* DbeDestroyWindow() */
1529
1530 \f
1531 /******************************************************************************
1532  *
1533  * DBE DIX Procedure: DbeExtensionInit
1534  *
1535  * Description:
1536  *
1537  *     Called from InitExtensions in main()
1538  *
1539  *****************************************************************************/
1540
1541 void
1542 DbeExtensionInit(void)
1543 {
1544     ExtensionEntry      *extEntry;
1545     register int        i, j;
1546     ScreenPtr           pScreen = NULL;
1547     DbeScreenPrivPtr    pDbeScreenPriv;
1548     int                 nStubbedScreens = 0;
1549     Bool                ddxInitSuccess;
1550
1551 #ifdef PANORAMIX
1552     if(!noPanoramiXExtension) return;
1553 #endif
1554
1555     /* Create the resource types. */
1556     dbeDrawableResType =
1557         CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
1558     if (!dbeDrawableResType)
1559         return;
1560     dbeDrawableResType |= RC_DRAWABLE;
1561
1562     dbeWindowPrivResType =
1563         CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
1564     if (!dbeWindowPrivResType)
1565         return;
1566
1567     if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0))
1568         return;
1569
1570     if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0))
1571         return;
1572
1573     for (i = 0; i < screenInfo.numScreens; i++)
1574     {
1575         /* For each screen, set up DBE screen privates and init DIX and DDX
1576          * interface.
1577          */
1578
1579         pScreen = screenInfo.screens[i];
1580
1581         if (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec))))
1582         {
1583             /* If we can not alloc a window or screen private,
1584              * then free any privates that we already alloc'ed and return
1585              */
1586
1587             for (j = 0; j < i; j++)
1588             {
1589                 free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates,
1590                                        dbeScreenPrivKey));
1591                 dixSetPrivate(&screenInfo.screens[j]->devPrivates,
1592                               dbeScreenPrivKey, NULL);
1593             }
1594             return;
1595         }
1596
1597         dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv);
1598
1599         {
1600             /* We don't have DDX support for DBE anymore */
1601
1602 #ifndef DISABLE_MI_DBE_BY_DEFAULT
1603             /* Setup DIX. */
1604             pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; 
1605
1606             /* Setup DDX. */
1607             ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
1608
1609             /* DDX DBE initialization may have the side affect of
1610              * reallocating pDbeScreenPriv, so we need to update it.
1611              */
1612             pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1613
1614             if (ddxInitSuccess)
1615             {
1616                 /* Wrap DestroyWindow.  The DDX initialization function
1617                  * already wrapped PositionWindow for us.
1618                  */
1619
1620                 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
1621                 pScreen->DestroyWindow        = DbeDestroyWindow;
1622             }
1623             else
1624             {
1625                 /* DDX initialization failed.  Stub the screen. */
1626                 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
1627             }
1628 #else
1629             DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
1630 #endif
1631
1632         }
1633
1634     } /* for (i = 0; i < screenInfo.numScreens; i++) */
1635
1636
1637     if (nStubbedScreens == screenInfo.numScreens)
1638     {
1639         /* All screens stubbed.  Clean up and return. */
1640
1641         for (i = 0; i < screenInfo.numScreens; i++)
1642         {
1643                 free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates,
1644                                        dbeScreenPrivKey));
1645                 dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
1646         }
1647         return;
1648     }
1649
1650
1651     /* Now add the extension. */
1652     extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, 
1653                             DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
1654                             DbeResetProc, StandardMinorOpcode);
1655
1656     dbeErrorBase = extEntry->errorBase;
1657     SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer);
1658     SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer);
1659
1660 } /* DbeExtensionInit() */
1661