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