1 /******************************************************************************
3 * Copyright (c) 1994, 1995 Hewlett-Packard Company
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
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.
31 *****************************************************************************/
36 #ifdef HAVE_DIX_CONFIG_H
37 #include <dix-config.h>
43 #elif !defined(UINT32_MAX)
44 #define UINT32_MAX 0xffffffffU
48 #include <X11/Xproto.h>
49 #include "scrnintstr.h"
50 #include "extnsionst.h"
52 #include "dixstruct.h"
53 #define NEED_DBE_PROTOCOL
54 #include "dbestruct.h"
60 /* These are globals for use by DDX */
61 DevPrivateKeyRec dbeScreenPrivKeyRec;
62 DevPrivateKeyRec dbeWindowPrivKeyRec;
64 /* These are globals for use by DDX */
65 RESTYPE dbeDrawableResType;
66 RESTYPE dbeWindowPrivResType;
68 /* Used to generate DBE's BadBuffer error. */
69 static int dbeErrorBase;
71 /******************************************************************************
73 * DBE DIX Procedure: DbeStubScreen
77 * This is function stubs the function pointers in the given DBE screen
78 * private and increments the number of stubbed screens.
80 *****************************************************************************/
83 DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
86 pDbeScreenPriv->SetupBackgroundPainter = NULL;
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.
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;
103 (*nStubbedScreens)++;
105 } /* DbeStubScreen() */
109 /******************************************************************************
111 * DBE DIX Procedure: ProcDbeGetVersion
115 * This function is for processing a DbeGetVersion request.
116 * This request returns the major and minor version numbers of this
123 *****************************************************************************/
126 ProcDbeGetVersion(ClientPtr client)
128 /* REQUEST(xDbeGetVersionReq); */
129 xDbeGetVersionReply rep;
133 REQUEST_SIZE_MATCH(xDbeGetVersionReq);
137 rep.sequenceNumber = client->sequence;
138 rep.majorVersion = DBE_MAJOR_VERSION;
139 rep.minorVersion = DBE_MINOR_VERSION;
143 swaps(&rep.sequenceNumber, n);
146 WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep);
150 } /* ProcDbeGetVersion() */
153 /******************************************************************************
155 * DBE DIX Procedure: ProcDbeAllocateBackBufferName
159 * This function is for processing a DbeAllocateBackBufferName request.
160 * This request allocates a drawable ID used to refer to the back buffer
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
170 * BadValue - invalid swap action is specified
171 * BadWindow - window is not a valid window
174 *****************************************************************************/
177 ProcDbeAllocateBackBufferName(ClientPtr client)
179 REQUEST(xDbeAllocateBackBufferNameReq);
181 DbeScreenPrivPtr pDbeScreenPriv;
182 DbeWindowPrivPtr pDbeWindowPriv;
183 XdbeScreenVisualInfo scrVisInfo;
185 Bool visualMatched = FALSE;
186 xDbeSwapAction swapAction;
192 REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
194 /* The window must be valid. */
195 status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
196 if (status != Success)
199 /* The window must be InputOutput. */
200 if (pWin->drawable.class != InputOutput)
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 ))
215 /* The id must be in range and not already in use. */
216 LEGAL_NEW_RESOURCE(stuff->buffer, client);
218 /* The visual of the window must be in the list returned by
221 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
222 if (!pDbeScreenPriv->GetVisualInfo)
223 return BadMatch; /* screen doesn't support double buffering */
225 if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
227 /* GetVisualInfo() failed to allocate visual info data. */
231 /* See if the window's visual is on the list. */
232 visual = wVisual(pWin);
233 for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++)
235 if (scrVisInfo.visinfo[i].visual == visual)
237 visualMatched = TRUE;
241 /* Free what was allocated by the GetVisualInfo() call above. */
242 free(scrVisInfo.visinfo);
249 if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
251 /* There is no buffer associated with the window.
252 * Allocate a window priv.
255 pDbeWindowPriv = dixAllocateObjectWithPrivates(DbeWindowPrivRec, PRIVATE_DBE_WINDOW);
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;
267 /* Set the buffer ID array pointer to the initial (static) array). */
268 pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
270 /* Initialize the buffer ID list. */
271 pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
272 pDbeWindowPriv->IDs[0] = stuff->buffer;
275 for (i = 0; i < DBE_INIT_MAX_IDS; i++)
277 pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
280 /* Actually connect the window priv to the window. */
281 dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
283 } /* if -- There is no buffer associated with the window. */
287 /* A buffer is already associated with the window.
288 * Add the new buffer ID to the array, reallocating the array memory
292 /* Determine if there is a free element in the ID array. */
293 for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++)
295 if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT)
297 /* There is still room in the ID array. */
302 if (i == pDbeWindowPriv->maxAvailableIDs)
304 /* No more room in the ID array -- reallocate another array. */
307 /* Setup an array pointer for the realloc operation below. */
308 if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
310 /* We will malloc a new array. */
315 /* We will realloc a new array. */
316 pIDs = pDbeWindowPriv->IDs;
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)
326 memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
327 (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
328 pDbeWindowPriv->nBufferIDs) * sizeof(XID));
330 if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
332 /* We just went from using the initial (static) array to a
333 * newly allocated array. Copy the IDs from the initial array
336 memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
337 DBE_INIT_MAX_IDS * sizeof(XID));
340 pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
345 } /* else -- A buffer is already associated with the window. */
348 /* Call the DDX routine to allocate the back buffer. */
349 status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
352 if (status == Success)
354 pDbeWindowPriv->IDs[add_index] = stuff->buffer;
355 if (!AddResource(stuff->buffer, dbeWindowPrivResType,
356 (pointer)pDbeWindowPriv))
358 pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
360 if (pDbeWindowPriv->nBufferIDs == 0) {
366 /* The DDX buffer allocation routine failed for the first buffer of
369 if (pDbeWindowPriv->nBufferIDs == 0) {
374 /* Increment the number of buffers (XIDs) associated with this window. */
375 pDbeWindowPriv->nBufferIDs++;
377 /* Set swap action on all calls. */
378 pDbeWindowPriv->swapAction = stuff->swapAction;
383 dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
384 free(pDbeWindowPriv);
387 } /* ProcDbeAllocateBackBufferName() */
390 /******************************************************************************
392 * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
396 * This function is for processing a DbeDeallocateBackBufferName request.
397 * This request frees a drawable ID that was obtained by a
398 * DbeAllocateBackBufferName request.
402 * BadBuffer - buffer to deallocate is not associated with a window
405 *****************************************************************************/
408 ProcDbeDeallocateBackBufferName(ClientPtr client)
410 REQUEST(xDbeDeallocateBackBufferNameReq);
411 DbeWindowPrivPtr pDbeWindowPriv;
416 REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
418 /* Buffer name must be valid */
419 rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
420 dbeWindowPrivResType, client,
425 rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
426 client, DixDestroyAccess);
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
435 for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
437 /* Loop through the ID list to find the ID. */
438 if (pDbeWindowPriv->IDs[i] == stuff->buffer)
444 if (i == pDbeWindowPriv->nBufferIDs)
446 /* We did not find the ID in the ID list. */
447 client->errorValue = stuff->buffer;
448 return dbeErrorBase + DbeBadBuffer;
451 FreeResource(stuff->buffer, RT_NONE);
455 } /* ProcDbeDeallocateBackBufferName() */
458 /******************************************************************************
460 * DBE DIX Procedure: ProcDbeSwapBuffers
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.
470 * BadAlloc - local allocation failed; this return value is not defined
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
476 * BadWindow - a window in request is not valid
479 *****************************************************************************/
482 ProcDbeSwapBuffers(ClientPtr client)
484 REQUEST(xDbeSwapBuffersReq);
486 DbeScreenPrivPtr pDbeScreenPriv;
487 DbeSwapInfoPtr swapInfo;
488 xDbeSwapInfo *dbeSwapInfo;
494 REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
495 nStuff = stuff->n; /* use local variable for performance. */
502 if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
505 /* Get to the swap info appended to the end of the request. */
506 dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
508 /* Allocate array to record swap information. */
509 swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec));
510 if (swapInfo == NULL)
516 for (i = 0; i < nStuff; i++)
518 /* Check all windows to swap. */
520 /* Each window must be a valid window - BadWindow. */
521 error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
523 if (error != Success) {
528 /* Each window must be double-buffered - BadMatch. */
529 if (DBE_WINDOW_PRIV(pWin) == NULL)
535 /* Each window must only be specified once - BadMatch. */
536 for (j = i + 1; j < nStuff; j++)
538 if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
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 ))
555 /* Everything checks out OK. Fill in the swap info array. */
556 swapInfo[i].pWindow = pWin;
557 swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
559 } /* for (i = 0; i < nStuff; i++) */
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.
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.
577 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
578 error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo);
579 if (error != Success)
589 } /* ProcDbeSwapBuffers() */
592 /******************************************************************************
594 * DBE DIX Procedure: ProcDbeBeginIdiom
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.
606 *****************************************************************************/
609 ProcDbeBeginIdiom(ClientPtr client)
611 /* REQUEST(xDbeBeginIdiomReq); */
612 DbeScreenPrivPtr pDbeScreenPriv;
616 REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
618 for (i = 0; i < screenInfo.numScreens; i++)
620 pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
622 /* Call the DDX begin idiom procedure if there is one. */
623 if (pDbeScreenPriv->BeginIdiom)
625 (*pDbeScreenPriv->BeginIdiom)(client);
631 } /* ProcDbeBeginIdiom() */
634 /******************************************************************************
636 * DBE DIX Procedure: ProcDbeGetVisualInfo
640 * This function is for processing a ProcDbeGetVisualInfo request.
641 * This request returns information about which visuals support
646 * BadDrawable - value in screen specifiers is not a valid drawable
649 *****************************************************************************/
652 ProcDbeGetVisualInfo(ClientPtr client)
654 REQUEST(xDbeGetVisualInfoReq);
655 DbeScreenPrivPtr pDbeScreenPriv;
656 xDbeGetVisualInfoReply rep;
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 */
663 XdbeScreenVisualInfo *pScrVisInfo;
666 REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
668 if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
670 /* Make sure any specified drawables are valid. */
673 if (!(pDrawables = (DrawablePtr *)malloc(stuff->n *
674 sizeof(DrawablePtr))))
679 drawables = (Drawable *)&stuff[1];
681 for (i = 0; i < stuff->n; i++)
683 rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0,
692 count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
693 if (!(pScrVisInfo = (XdbeScreenVisualInfo *)malloc(count *
694 sizeof(XdbeScreenVisualInfo))))
703 for (i = 0; i < count; i++)
705 pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
706 pDrawables[i]->pScreen;
707 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
709 rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
710 if ((rc != Success) ||
711 !(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
713 /* We failed to alloc pScrVisInfo[i].visinfo. */
715 /* Free visinfos that we allocated for previous screen infos.*/
716 for (j = 0; j < i; j++)
718 free(pScrVisInfo[j].visinfo);
721 /* Free pDrawables if we needed to allocate it above. */
724 return (rc == Success) ? BadAlloc : rc;
727 /* Account for n, number of xDbeVisInfo items in list. */
728 length += sizeof(CARD32);
730 /* Account for n xDbeVisInfo items */
731 length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
735 rep.sequenceNumber = client->sequence;
736 rep.length = bytes_to_int32(length);
741 swaps(&rep.sequenceNumber, n);
742 swapl(&rep.length, n);
746 /* Send off reply. */
747 WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep);
749 for (i = 0; i < count; i++)
753 /* For each screen in the reply, send off the visual info */
755 /* Send off number of visuals. */
756 data32 = (CARD32)pScrVisInfo[i].count;
763 WriteToClient(client, sizeof(CARD32), (char *)&data32);
765 /* Now send off visual info items. */
766 for (j = 0; j < pScrVisInfo[i].count; j++)
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.
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;
781 swapl(&visInfo.visualID, n);
783 /* We do not need to swap depth and perfLevel since they are
784 * already 1 byte quantities.
788 /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
789 WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID);
793 /* Clean up memory. */
794 for (i = 0; i < count; i++)
796 free(pScrVisInfo[i].visinfo);
804 } /* ProcDbeGetVisualInfo() */
807 /******************************************************************************
809 * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
813 * This function is for processing a ProcDbeGetbackBufferAttributes
814 * request. This request returns information about a back buffer.
820 *****************************************************************************/
823 ProcDbeGetBackBufferAttributes(ClientPtr client)
825 REQUEST(xDbeGetBackBufferAttributesReq);
826 xDbeGetBackBufferAttributesReply rep;
827 DbeWindowPrivPtr pDbeWindowPriv;
831 REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
833 rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
834 dbeWindowPrivResType, client,
838 rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
842 rep.attributes = None;
846 rep.sequenceNumber = client->sequence;
851 swaps(&rep.sequenceNumber, n);
852 swapl(&rep.length, n);
853 swapl(&rep.attributes, n);
856 WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
860 } /* ProcDbeGetbackBufferAttributes() */
863 /******************************************************************************
865 * DBE DIX Procedure: ProcDbeDispatch
869 * This function dispatches DBE requests.
871 *****************************************************************************/
874 ProcDbeDispatch(ClientPtr client)
881 case X_DbeGetVersion:
882 return(ProcDbeGetVersion(client));
884 case X_DbeAllocateBackBufferName:
885 return(ProcDbeAllocateBackBufferName(client));
887 case X_DbeDeallocateBackBufferName:
888 return(ProcDbeDeallocateBackBufferName(client));
890 case X_DbeSwapBuffers:
891 return(ProcDbeSwapBuffers(client));
893 case X_DbeBeginIdiom:
894 return(ProcDbeBeginIdiom(client));
899 case X_DbeGetVisualInfo:
900 return(ProcDbeGetVisualInfo(client));
902 case X_DbeGetBackBufferAttributes:
903 return(ProcDbeGetBackBufferAttributes(client));
909 } /* ProcDbeDispatch() */
912 /******************************************************************************
914 * DBE DIX Procedure: SProcDbeGetVersion
918 * This function is for processing a DbeGetVersion request on a swapped
919 * server. This request returns the major and minor version numbers of
926 *****************************************************************************/
929 SProcDbeGetVersion(ClientPtr client)
931 REQUEST(xDbeGetVersionReq);
935 swaps(&stuff->length, n);
936 return(ProcDbeGetVersion(client));
938 } /* SProcDbeGetVersion() */
941 /******************************************************************************
943 * DBE DIX Procedure: SProcDbeAllocateBackBufferName
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.
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
958 * BadValue - invalid swap action is specified
959 * BadWindow - window is not a valid window
962 *****************************************************************************/
965 SProcDbeAllocateBackBufferName(ClientPtr client)
967 REQUEST(xDbeAllocateBackBufferNameReq);
970 swaps(&stuff->length, n);
971 REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
973 swapl(&stuff->window, n);
974 swapl(&stuff->buffer, n);
975 /* stuff->swapAction is a byte. We do not need to swap this field. */
977 return(ProcDbeAllocateBackBufferName(client));
979 } /* SProcDbeAllocateBackBufferName() */
982 /******************************************************************************
984 * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
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.
994 * BadBuffer - buffer to deallocate is not associated with a window
997 *****************************************************************************/
1000 SProcDbeDeallocateBackBufferName(ClientPtr client)
1002 REQUEST (xDbeDeallocateBackBufferNameReq);
1006 swaps(&stuff->length, n);
1007 REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
1009 swapl(&stuff->buffer, n);
1011 return(ProcDbeDeallocateBackBufferName(client));
1013 } /* SProcDbeDeallocateBackBufferName() */
1016 /******************************************************************************
1018 * DBE DIX Procedure: SProcDbeSwapBuffers
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.
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
1035 *****************************************************************************/
1038 SProcDbeSwapBuffers(ClientPtr client)
1040 REQUEST(xDbeSwapBuffersReq);
1042 xDbeSwapInfo *pSwapInfo;
1045 swaps(&stuff->length, n);
1046 REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
1048 swapl(&stuff->n, n);
1052 pSwapInfo = (xDbeSwapInfo *)stuff+1;
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.
1058 for (i = 0; i < stuff->n; i++)
1060 swapl(&pSwapInfo->window, n);
1064 return(ProcDbeSwapBuffers(client));
1066 } /* SProcDbeSwapBuffers() */
1069 /******************************************************************************
1071 * DBE DIX Procedure: SProcDbeBeginIdiom
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.
1083 *****************************************************************************/
1086 SProcDbeBeginIdiom(ClientPtr client)
1088 REQUEST(xDbeBeginIdiomReq);
1091 swaps(&stuff->length, n);
1092 return(ProcDbeBeginIdiom(client));
1094 } /* SProcDbeBeginIdiom() */
1097 /******************************************************************************
1099 * DBE DIX Procedure: SProcDbeGetVisualInfo
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.
1109 * BadDrawable - value in screen specifiers is not a valid drawable
1112 *****************************************************************************/
1115 SProcDbeGetVisualInfo(ClientPtr client)
1117 REQUEST(xDbeGetVisualInfoReq);
1121 swaps(&stuff->length, n);
1122 REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
1124 swapl(&stuff->n, n);
1127 return(ProcDbeGetVisualInfo(client));
1129 } /* SProcDbeGetVisualInfo() */
1132 /******************************************************************************
1134 * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
1138 * This function is for processing a ProcDbeGetbackBufferAttributes
1139 * request on a swapped server. This request returns information about a
1146 *****************************************************************************/
1149 SProcDbeGetBackBufferAttributes(ClientPtr client)
1151 REQUEST (xDbeGetBackBufferAttributesReq);
1154 swaps(&stuff->length, n);
1155 REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
1157 swapl(&stuff->buffer, n);
1159 return(ProcDbeGetBackBufferAttributes(client));
1161 } /* SProcDbeGetBackBufferAttributes() */
1164 /******************************************************************************
1166 * DBE DIX Procedure: SProcDbeDispatch
1170 * This function dispatches DBE requests on a swapped server.
1172 *****************************************************************************/
1175 SProcDbeDispatch(ClientPtr client)
1180 switch (stuff->data)
1182 case X_DbeGetVersion:
1183 return(SProcDbeGetVersion(client));
1185 case X_DbeAllocateBackBufferName:
1186 return(SProcDbeAllocateBackBufferName(client));
1188 case X_DbeDeallocateBackBufferName:
1189 return(SProcDbeDeallocateBackBufferName(client));
1191 case X_DbeSwapBuffers:
1192 return(SProcDbeSwapBuffers(client));
1194 case X_DbeBeginIdiom:
1195 return(SProcDbeBeginIdiom(client));
1200 case X_DbeGetVisualInfo:
1201 return(SProcDbeGetVisualInfo(client));
1203 case X_DbeGetBackBufferAttributes:
1204 return(SProcDbeGetBackBufferAttributes(client));
1210 } /* SProcDbeDispatch() */
1213 /******************************************************************************
1215 * DBE DIX Procedure: DbeSetupBackgroundPainter
1219 * This function sets up pGC to clear pixmaps.
1223 * TRUE - setup was successful
1224 * FALSE - the window's background state is NONE
1226 *****************************************************************************/
1229 DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
1231 ChangeGCVal gcvalues[4];
1232 int ts_x_origin, ts_y_origin;
1233 PixUnion background;
1234 int backgroundState;
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.
1243 ts_x_origin = ts_y_origin = 0;
1244 while (pWin->backgroundState == ParentRelative)
1246 ts_x_origin -= pWin->origin.x;
1247 ts_y_origin -= pWin->origin.y;
1249 pWin = pWin->parent;
1251 backgroundState = pWin->backgroundState;
1252 background = pWin->background;
1254 switch (backgroundState)
1256 case BackgroundPixel:
1257 gcvalues[0].val = background.pixel;
1258 gcvalues[1].val = FillSolid;
1259 gcmask = GCForeground|GCFillStyle;
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;
1271 /* pWin->backgroundState == None */
1275 return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
1276 } /* DbeSetupBackgroundPainter() */
1279 /******************************************************************************
1281 * DBE DIX Procedure: DbeDrawableDelete
1285 * This is the resource delete function for dbeDrawableResType.
1286 * It is registered when the drawable resource type is created in
1287 * DbeExtensionInit().
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.
1294 *****************************************************************************/
1296 DbeDrawableDelete(pointer pDrawable, XID id)
1300 } /* DbeDrawableDelete() */
1303 /******************************************************************************
1305 * DBE DIX Procedure: DbeWindowPrivDelete
1309 * This is the resource delete function for dbeWindowPrivResType.
1310 * It is registered when the drawable resource type is created in
1311 * DbeExtensionInit().
1313 *****************************************************************************/
1315 DbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
1317 DbeScreenPrivPtr pDbeScreenPriv;
1318 DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv;
1323 **************************************************************************
1324 ** Remove the buffer ID from the ID array.
1325 **************************************************************************
1328 /* Find the ID in the ID array. */
1330 while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id))
1335 if (i == pDbeWindowPriv->nBufferIDs)
1337 /* We did not find the ID in the array. We should never get here. */
1341 /* Remove the ID from the array. */
1343 if (i < (pDbeWindowPriv->nBufferIDs - 1))
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));
1351 /* We are removing the last ID in the array, in which case, the
1352 * assignement below is all that we need to do.
1355 pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
1357 pDbeWindowPriv->nBufferIDs--;
1359 /* If an extended array was allocated, then check to see if the remaining
1360 * buffer IDs will fit in the static array.
1363 if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) &&
1364 (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS))
1366 /* Copy the IDs back into the static array. */
1367 memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
1368 DBE_INIT_MAX_IDS * sizeof(XID));
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;
1378 **************************************************************************
1379 ** Perform DDX level tasks.
1380 **************************************************************************
1383 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(
1384 (DbeWindowPrivPtr)pDbeWindowPriv);
1385 (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id);
1389 **************************************************************************
1390 ** Perform miscellaneous tasks if this is the last buffer associated
1392 **************************************************************************
1395 if (pDbeWindowPriv->nBufferIDs == 0)
1397 /* Reset the DBE window priv pointer. */
1398 dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
1401 /* We are done with the window priv. */
1402 dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW);
1407 } /* DbeWindowPrivDelete() */
1410 /******************************************************************************
1412 * DBE DIX Procedure: DbeResetProc
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.
1420 *****************************************************************************/
1422 DbeResetProc(ExtensionEntry *extEntry)
1426 DbeScreenPrivPtr pDbeScreenPriv;
1428 for (i = 0; i < screenInfo.numScreens; i++)
1430 pScreen = screenInfo.screens[i];
1431 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1435 /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/
1436 pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1438 if (pDbeScreenPriv->ResetProc)
1439 (*pDbeScreenPriv->ResetProc)(pScreen);
1441 free(pDbeScreenPriv);
1444 } /* DbeResetProc() */
1447 /******************************************************************************
1449 * DBE DIX Procedure: DbeDestroyWindow
1453 * This is the wrapper for pScreen->DestroyWindow.
1454 * This function frees buffer resources for a window before it is
1457 *****************************************************************************/
1460 DbeDestroyWindow(WindowPtr pWin)
1462 DbeScreenPrivPtr pDbeScreenPriv;
1463 DbeWindowPrivPtr pDbeWindowPriv;
1469 **************************************************************************
1470 ** 1. Unwrap the member routine.
1471 **************************************************************************
1474 pScreen = pWin->drawable.pScreen;
1475 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1476 pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1479 **************************************************************************
1480 ** 2. Do any work necessary before the member routine is called.
1482 ** Call the window priv delete function for all buffer IDs associated
1483 ** with this window.
1484 **************************************************************************
1487 if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
1489 while (pDbeWindowPriv)
1491 /* *DbeWinPrivDelete() will free the window private and set it to
1492 * NULL if there are no more buffer IDs associated with this
1495 FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
1496 pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
1501 **************************************************************************
1502 ** 3. Call the member routine, saving its result if necessary.
1503 **************************************************************************
1506 ret = (*pScreen->DestroyWindow)(pWin);
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 **************************************************************************
1515 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
1516 pScreen->DestroyWindow = DbeDestroyWindow;
1519 **************************************************************************
1520 ** 5. Do any work necessary after the member routine has been called.
1522 ** In this case we do not need to do anything.
1523 **************************************************************************
1528 } /* DbeDestroyWindow() */
1531 /******************************************************************************
1533 * DBE DIX Procedure: DbeExtensionInit
1537 * Called from InitExtensions in main()
1539 *****************************************************************************/
1542 DbeExtensionInit(void)
1544 ExtensionEntry *extEntry;
1546 ScreenPtr pScreen = NULL;
1547 DbeScreenPrivPtr pDbeScreenPriv;
1548 int nStubbedScreens = 0;
1549 Bool ddxInitSuccess;
1552 if(!noPanoramiXExtension) return;
1555 /* Create the resource types. */
1556 dbeDrawableResType =
1557 CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
1558 if (!dbeDrawableResType)
1560 dbeDrawableResType |= RC_DRAWABLE;
1562 dbeWindowPrivResType =
1563 CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
1564 if (!dbeWindowPrivResType)
1567 if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0))
1570 if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0))
1573 for (i = 0; i < screenInfo.numScreens; i++)
1575 /* For each screen, set up DBE screen privates and init DIX and DDX
1579 pScreen = screenInfo.screens[i];
1581 if (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec))))
1583 /* If we can not alloc a window or screen private,
1584 * then free any privates that we already alloc'ed and return
1587 for (j = 0; j < i; j++)
1589 free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates,
1591 dixSetPrivate(&screenInfo.screens[j]->devPrivates,
1592 dbeScreenPrivKey, NULL);
1597 dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv);
1600 /* We don't have DDX support for DBE anymore */
1602 #ifndef DISABLE_MI_DBE_BY_DEFAULT
1604 pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
1607 ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
1609 /* DDX DBE initialization may have the side affect of
1610 * reallocating pDbeScreenPriv, so we need to update it.
1612 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
1616 /* Wrap DestroyWindow. The DDX initialization function
1617 * already wrapped PositionWindow for us.
1620 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
1621 pScreen->DestroyWindow = DbeDestroyWindow;
1625 /* DDX initialization failed. Stub the screen. */
1626 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
1629 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
1634 } /* for (i = 0; i < screenInfo.numScreens; i++) */
1637 if (nStubbedScreens == screenInfo.numScreens)
1639 /* All screens stubbed. Clean up and return. */
1641 for (i = 0; i < screenInfo.numScreens; i++)
1643 free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates,
1645 dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
1651 /* Now add the extension. */
1652 extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
1653 DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
1654 DbeResetProc, StandardMinorOpcode);
1656 dbeErrorBase = extEntry->errorBase;
1657 SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer);
1658 SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer);
1660 } /* DbeExtensionInit() */