From d9f970a847e1af706f07560ef163b229bb592307 Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 1 Jul 2011 14:21:21 +0200 Subject: xwininfo libX11 mesa mkfontscale xserver xkeyboard-config git update 1 Juli 2011 --- xorg-server/hw/xfree86/dri2/dri2.h | 574 +++++++-------- xorg-server/hw/xfree86/dri2/dri2ext.c | 1299 ++++++++++++++++----------------- 2 files changed, 936 insertions(+), 937 deletions(-) (limited to 'xorg-server/hw/xfree86/dri2') diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h index afe2083de..2a41ead5b 100644 --- a/xorg-server/hw/xfree86/dri2/dri2.h +++ b/xorg-server/hw/xfree86/dri2/dri2.h @@ -1,287 +1,287 @@ -/* - * Copyright © 2007 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kristian Høgsberg (krh@redhat.com) - */ - -#ifndef _DRI2_H_ -#define _DRI2_H_ - -#include - -/* Version 2 structure (with format at the end) */ -typedef struct { - unsigned int attachment; - unsigned int name; - unsigned int pitch; - unsigned int cpp; - unsigned int flags; - unsigned int format; - void *driverPrivate; -} DRI2BufferRec, *DRI2BufferPtr; - -extern CARD8 dri2_major; /* version of DRI2 supported by DDX */ -extern CARD8 dri2_minor; - -typedef DRI2BufferRec DRI2Buffer2Rec, *DRI2Buffer2Ptr; -typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type, - CARD64 ust, CARD64 msc, CARD64 sbc); - - -typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw, - unsigned int *attachments, - int count); -typedef void (*DRI2DestroyBuffersProcPtr)(DrawablePtr pDraw, - DRI2BufferPtr buffers, - int count); -typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw, - RegionPtr pRegion, - DRI2BufferPtr pDestBuffer, - DRI2BufferPtr pSrcBuffer); -typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, - unsigned int sequence); -typedef int (*DRI2AuthMagicProcPtr)(int fd, uint32_t magic); - -/** - * Schedule a buffer swap - * - * This callback is used to support glXSwapBuffers and the OML_sync_control - * extension (see it for a description of the params). - * - * Drivers should queue an event for the frame count that satisfies the - * parameters passed in. If the event is in the future (i.e. the conditions - * aren't currently satisfied), the server may block the client at the next - * GLX request using DRI2WaitSwap. When the event arrives, drivers should call - * \c DRI2SwapComplete, which will handle waking the client and returning - * the appropriate data. - * - * The DDX is responsible for doing a flip, exchange, or blit of the swap - * when the corresponding event arrives. The \c DRI2CanFlip and - * \c DRI2CanExchange functions can be used as helpers for this purpose. - * - * \param client client pointer (used for block/unblock) - * \param pDraw drawable whose count we want - * \param pDestBuffer current front buffer - * \param pSrcBuffer current back buffer - * \param target_msc frame count to wait for - * \param divisor divisor for condition equation - * \param remainder remainder for division equation - * \param func function to call when the swap completes - * \param data data for the callback \p func. - */ -typedef int (*DRI2ScheduleSwapProcPtr)(ClientPtr client, - DrawablePtr pDraw, - DRI2BufferPtr pDestBuffer, - DRI2BufferPtr pSrcBuffer, - CARD64 *target_msc, - CARD64 divisor, - CARD64 remainder, - DRI2SwapEventPtr func, - void *data); -typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw, - unsigned int attachment, - unsigned int format); -typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw, - DRI2BufferPtr buffer); -/** - * Get current media stamp counter values - * - * This callback is used to support the SGI_video_sync and OML_sync_control - * extensions. - * - * Drivers should return the current frame counter and the timestamp from - * when the returned frame count was last incremented. - * - * The count should correspond to the screen where the drawable is currently - * visible. If the drawable isn't visible (e.g. redirected), the server - * should return BadDrawable to the client, pending GLX spec updates to - * define this behavior. - * - * \param pDraw drawable whose count we want - * \param ust timestamp from when the count was last incremented. - * \param mst current frame count - */ -typedef int (*DRI2GetMSCProcPtr)(DrawablePtr pDraw, CARD64 *ust, - CARD64 *msc); -/** - * Schedule a frame count related wait - * - * This callback is used to support the SGI_video_sync and OML_sync_control - * extensions. See those specifications for details on how to handle - * the divisor and remainder parameters. - * - * Drivers should queue an event for the frame count that satisfies the - * parameters passed in. If the event is in the future (i.e. the conditions - * aren't currently satisfied), the driver should block the client using - * \c DRI2BlockClient. When the event arrives, drivers should call - * \c DRI2WaitMSCComplete, which will handle waking the client and returning - * the appropriate data. - * - * \param client client pointer (used for block/unblock) - * \param pDraw drawable whose count we want - * \param target_msc frame count to wait for - * \param divisor divisor for condition equation - * \param remainder remainder for division equation - */ -typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client, - DrawablePtr pDraw, - CARD64 target_msc, - CARD64 divisor, - CARD64 remainder); - -typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw, - void *data); - -/** - * Version of the DRI2InfoRec structure defined in this header - */ -#define DRI2INFOREC_VERSION 5 - -typedef struct { - unsigned int version; /**< Version of this struct */ - int fd; - const char *driverName; - const char *deviceName; - - DRI2CreateBufferProcPtr CreateBuffer; - DRI2DestroyBufferProcPtr DestroyBuffer; - DRI2CopyRegionProcPtr CopyRegion; - DRI2WaitProcPtr Wait; - - /* added in version 4 */ - - DRI2ScheduleSwapProcPtr ScheduleSwap; - DRI2GetMSCProcPtr GetMSC; - DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; - - /* number of drivers in the driverNames array */ - unsigned int numDrivers; - /* array of driver names, indexed by DRI2Driver* driver types */ - /* a name of NULL means that driver is not supported */ - const char * const *driverNames; - - /* added in version 5 */ - - DRI2AuthMagicProcPtr AuthMagic; -} DRI2InfoRec, *DRI2InfoPtr; - -extern _X_EXPORT int DRI2EventBase; - -extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, - DRI2InfoPtr info); - -extern _X_EXPORT void DRI2CloseScreen(ScreenPtr pScreen); - -extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen); - -extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen, - unsigned int driverType, - int *fd, - const char **driverName, - const char **deviceName); - -extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic); - -extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client, - DrawablePtr pDraw, - XID id, - DRI2InvalidateProcPtr invalidate, - void *priv); - -extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); - -extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw, - int *width, - int *height, - unsigned int *attachments, - int count, - int *out_count); - -extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw, - RegionPtr pRegion, - unsigned int dest, - unsigned int src); - -/** - * Determine the major and minor version of the DRI2 extension. - * - * Provides a mechanism to other modules (e.g., 2D drivers) to determine the - * version of the DRI2 extension. While it is possible to peek directly at - * the \c XF86ModuleData from a layered module, such a module will fail to - * load (due to an unresolved symbol) if the DRI2 extension is not loaded. - * - * \param major Location to store the major verion of the DRI2 extension - * \param minor Location to store the minor verion of the DRI2 extension - * - * \note - * This interface was added some time after the initial release of the DRI2 - * module. Layered modules that wish to use this interface must first test - * its existance by calling \c xf86LoaderCheckSymbol. - */ -extern _X_EXPORT void DRI2Version(int *major, int *minor); - -extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, - int *width, int *height, unsigned int *attachments, int count, - int *out_count); - -extern _X_EXPORT void DRI2SwapInterval(DrawablePtr pDrawable, int interval); -extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDrawable, - CARD64 target_msc, CARD64 divisor, - CARD64 remainder, CARD64 *swap_target, - DRI2SwapEventPtr func, void *data); -extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable); - -extern _X_EXPORT int DRI2GetMSC(DrawablePtr pDrawable, CARD64 *ust, - CARD64 *msc, CARD64 *sbc); -extern _X_EXPORT int DRI2WaitMSC(ClientPtr client, DrawablePtr pDrawable, - CARD64 target_msc, CARD64 divisor, - CARD64 remainder); -extern _X_EXPORT int ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, - CARD64 msc, CARD64 sbc); -extern _X_EXPORT int DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, - CARD64 target_sbc); -extern _X_EXPORT Bool DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw); - -extern _X_EXPORT Bool DRI2CanFlip(DrawablePtr pDraw); - -extern _X_EXPORT Bool DRI2CanExchange(DrawablePtr pDraw); - -/* Note: use *only* for MSC related waits */ -extern _X_EXPORT void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw); - -extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, - int frame, unsigned int tv_sec, - unsigned int tv_usec, int type, - DRI2SwapEventPtr swap_complete, - void *swap_data); -extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, - int frame, unsigned int tv_sec, - unsigned int tv_usec); - -#endif +/* + * Copyright © 2007 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifndef _DRI2_H_ +#define _DRI2_H_ + +#include + +/* Version 2 structure (with format at the end) */ +typedef struct { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; + unsigned int format; + void *driverPrivate; +} DRI2BufferRec, *DRI2BufferPtr; + +extern CARD8 dri2_major; /* version of DRI2 supported by DDX */ +extern CARD8 dri2_minor; + +typedef DRI2BufferRec DRI2Buffer2Rec, *DRI2Buffer2Ptr; +typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type, + CARD64 ust, CARD64 msc, CARD32 sbc); + + +typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw, + unsigned int *attachments, + int count); +typedef void (*DRI2DestroyBuffersProcPtr)(DrawablePtr pDraw, + DRI2BufferPtr buffers, + int count); +typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw, + RegionPtr pRegion, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer); +typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, + unsigned int sequence); +typedef int (*DRI2AuthMagicProcPtr)(int fd, uint32_t magic); + +/** + * Schedule a buffer swap + * + * This callback is used to support glXSwapBuffers and the OML_sync_control + * extension (see it for a description of the params). + * + * Drivers should queue an event for the frame count that satisfies the + * parameters passed in. If the event is in the future (i.e. the conditions + * aren't currently satisfied), the server may block the client at the next + * GLX request using DRI2WaitSwap. When the event arrives, drivers should call + * \c DRI2SwapComplete, which will handle waking the client and returning + * the appropriate data. + * + * The DDX is responsible for doing a flip, exchange, or blit of the swap + * when the corresponding event arrives. The \c DRI2CanFlip and + * \c DRI2CanExchange functions can be used as helpers for this purpose. + * + * \param client client pointer (used for block/unblock) + * \param pDraw drawable whose count we want + * \param pDestBuffer current front buffer + * \param pSrcBuffer current back buffer + * \param target_msc frame count to wait for + * \param divisor divisor for condition equation + * \param remainder remainder for division equation + * \param func function to call when the swap completes + * \param data data for the callback \p func. + */ +typedef int (*DRI2ScheduleSwapProcPtr)(ClientPtr client, + DrawablePtr pDraw, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer, + CARD64 *target_msc, + CARD64 divisor, + CARD64 remainder, + DRI2SwapEventPtr func, + void *data); +typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw, + unsigned int attachment, + unsigned int format); +typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw, + DRI2BufferPtr buffer); +/** + * Get current media stamp counter values + * + * This callback is used to support the SGI_video_sync and OML_sync_control + * extensions. + * + * Drivers should return the current frame counter and the timestamp from + * when the returned frame count was last incremented. + * + * The count should correspond to the screen where the drawable is currently + * visible. If the drawable isn't visible (e.g. redirected), the server + * should return BadDrawable to the client, pending GLX spec updates to + * define this behavior. + * + * \param pDraw drawable whose count we want + * \param ust timestamp from when the count was last incremented. + * \param mst current frame count + */ +typedef int (*DRI2GetMSCProcPtr)(DrawablePtr pDraw, CARD64 *ust, + CARD64 *msc); +/** + * Schedule a frame count related wait + * + * This callback is used to support the SGI_video_sync and OML_sync_control + * extensions. See those specifications for details on how to handle + * the divisor and remainder parameters. + * + * Drivers should queue an event for the frame count that satisfies the + * parameters passed in. If the event is in the future (i.e. the conditions + * aren't currently satisfied), the driver should block the client using + * \c DRI2BlockClient. When the event arrives, drivers should call + * \c DRI2WaitMSCComplete, which will handle waking the client and returning + * the appropriate data. + * + * \param client client pointer (used for block/unblock) + * \param pDraw drawable whose count we want + * \param target_msc frame count to wait for + * \param divisor divisor for condition equation + * \param remainder remainder for division equation + */ +typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client, + DrawablePtr pDraw, + CARD64 target_msc, + CARD64 divisor, + CARD64 remainder); + +typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw, + void *data); + +/** + * Version of the DRI2InfoRec structure defined in this header + */ +#define DRI2INFOREC_VERSION 5 + +typedef struct { + unsigned int version; /**< Version of this struct */ + int fd; + const char *driverName; + const char *deviceName; + + DRI2CreateBufferProcPtr CreateBuffer; + DRI2DestroyBufferProcPtr DestroyBuffer; + DRI2CopyRegionProcPtr CopyRegion; + DRI2WaitProcPtr Wait; + + /* added in version 4 */ + + DRI2ScheduleSwapProcPtr ScheduleSwap; + DRI2GetMSCProcPtr GetMSC; + DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; + + /* number of drivers in the driverNames array */ + unsigned int numDrivers; + /* array of driver names, indexed by DRI2Driver* driver types */ + /* a name of NULL means that driver is not supported */ + const char * const *driverNames; + + /* added in version 5 */ + + DRI2AuthMagicProcPtr AuthMagic; +} DRI2InfoRec, *DRI2InfoPtr; + +extern _X_EXPORT int DRI2EventBase; + +extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, + DRI2InfoPtr info); + +extern _X_EXPORT void DRI2CloseScreen(ScreenPtr pScreen); + +extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen); + +extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen, + unsigned int driverType, + int *fd, + const char **driverName, + const char **deviceName); + +extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic); + +extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client, + DrawablePtr pDraw, + XID id, + DRI2InvalidateProcPtr invalidate, + void *priv); + +extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); + +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw, + int *width, + int *height, + unsigned int *attachments, + int count, + int *out_count); + +extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw, + RegionPtr pRegion, + unsigned int dest, + unsigned int src); + +/** + * Determine the major and minor version of the DRI2 extension. + * + * Provides a mechanism to other modules (e.g., 2D drivers) to determine the + * version of the DRI2 extension. While it is possible to peek directly at + * the \c XF86ModuleData from a layered module, such a module will fail to + * load (due to an unresolved symbol) if the DRI2 extension is not loaded. + * + * \param major Location to store the major verion of the DRI2 extension + * \param minor Location to store the minor verion of the DRI2 extension + * + * \note + * This interface was added some time after the initial release of the DRI2 + * module. Layered modules that wish to use this interface must first test + * its existance by calling \c xf86LoaderCheckSymbol. + */ +extern _X_EXPORT void DRI2Version(int *major, int *minor); + +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, + int *width, int *height, unsigned int *attachments, int count, + int *out_count); + +extern _X_EXPORT void DRI2SwapInterval(DrawablePtr pDrawable, int interval); +extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDrawable, + CARD64 target_msc, CARD64 divisor, + CARD64 remainder, CARD64 *swap_target, + DRI2SwapEventPtr func, void *data); +extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable); + +extern _X_EXPORT int DRI2GetMSC(DrawablePtr pDrawable, CARD64 *ust, + CARD64 *msc, CARD64 *sbc); +extern _X_EXPORT int DRI2WaitMSC(ClientPtr client, DrawablePtr pDrawable, + CARD64 target_msc, CARD64 divisor, + CARD64 remainder); +extern _X_EXPORT int ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, + CARD64 msc, CARD64 sbc); +extern _X_EXPORT int DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, + CARD64 target_sbc); +extern _X_EXPORT Bool DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw); + +extern _X_EXPORT Bool DRI2CanFlip(DrawablePtr pDraw); + +extern _X_EXPORT Bool DRI2CanExchange(DrawablePtr pDraw); + +/* Note: use *only* for MSC related waits */ +extern _X_EXPORT void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw); + +extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, + int frame, unsigned int tv_sec, + unsigned int tv_usec, int type, + DRI2SwapEventPtr swap_complete, + void *swap_data); +extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, + int frame, unsigned int tv_sec, + unsigned int tv_usec); + +#endif diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c index 6853fab9e..552b26b7c 100644 --- a/xorg-server/hw/xfree86/dri2/dri2ext.c +++ b/xorg-server/hw/xfree86/dri2/dri2ext.c @@ -1,650 +1,649 @@ -/* - * Copyright © 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kristian Høgsberg (krh@redhat.com) - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include "dixstruct.h" -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "xfixes.h" -#include "dri2.h" -#include "protocol-versions.h" - -/* The only xf86 include */ -#include "xf86Module.h" - -static ExtensionEntry *dri2Extension; - -static Bool -validDrawable(ClientPtr client, XID drawable, Mask access_mode, - DrawablePtr *pDrawable, int *status) -{ - *status = dixLookupDrawable(pDrawable, drawable, client, - M_DRAWABLE_WINDOW | M_DRAWABLE_PIXMAP, - access_mode); - if (*status != Success) { - client->errorValue = drawable; - return FALSE; - } - - return TRUE; -} - -static int -ProcDRI2QueryVersion(ClientPtr client) -{ - REQUEST(xDRI2QueryVersionReq); - xDRI2QueryVersionReply rep; - int n; - - if (client->swapped) - swaps(&stuff->length, n); - - REQUEST_SIZE_MATCH(xDRI2QueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = dri2_major; - rep.minorVersion = dri2_minor; - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - - WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep); - - return Success; -} - -static int -ProcDRI2Connect(ClientPtr client) -{ - REQUEST(xDRI2ConnectReq); - xDRI2ConnectReply rep; - DrawablePtr pDraw; - int fd, status; - const char *driverName; - const char *deviceName; - - REQUEST_SIZE_MATCH(xDRI2ConnectReq); - if (!validDrawable(client, stuff->window, DixGetAttrAccess, - &pDraw, &status)) - return status; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.driverNameLength = 0; - rep.deviceNameLength = 0; - - if (!DRI2Connect(pDraw->pScreen, - stuff->driverType, &fd, &driverName, &deviceName)) - goto fail; - - rep.driverNameLength = strlen(driverName); - rep.deviceNameLength = strlen(deviceName); - rep.length = (rep.driverNameLength + 3) / 4 + - (rep.deviceNameLength + 3) / 4; - - fail: - WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); - WriteToClient(client, rep.driverNameLength, driverName); - WriteToClient(client, rep.deviceNameLength, deviceName); - - return Success; -} - -static int -ProcDRI2Authenticate(ClientPtr client) -{ - REQUEST(xDRI2AuthenticateReq); - xDRI2AuthenticateReply rep; - DrawablePtr pDraw; - int status; - - REQUEST_SIZE_MATCH(xDRI2AuthenticateReq); - if (!validDrawable(client, stuff->window, DixGetAttrAccess, - &pDraw, &status)) - return status; - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic); - WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep); - - return Success; -} - -static void -DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv) -{ - xDRI2InvalidateBuffers event; - ClientPtr client = priv; - - event.type = DRI2EventBase + DRI2_InvalidateBuffers; - event.drawable = pDraw->id; - - WriteEventsToClient(client, 1, (xEvent *)&event); -} - -static int -ProcDRI2CreateDrawable(ClientPtr client) -{ - REQUEST(xDRI2CreateDrawableReq); - DrawablePtr pDrawable; - int status; - - REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); - - if (!validDrawable(client, stuff->drawable, DixAddAccess, - &pDrawable, &status)) - return status; - - status = DRI2CreateDrawable(client, pDrawable, stuff->drawable, - DRI2InvalidateBuffersEvent, client); - if (status != Success) - return status; - - return Success; -} - -static int -ProcDRI2DestroyDrawable(ClientPtr client) -{ - REQUEST(xDRI2DestroyDrawableReq); - DrawablePtr pDrawable; - int status; - - REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq); - if (!validDrawable(client, stuff->drawable, DixRemoveAccess, - &pDrawable, &status)) - return status; - - return Success; -} - - -static int -send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, - DRI2BufferPtr *buffers, int count, int width, int height) -{ - xDRI2GetBuffersReply rep; - int skip = 0; - int i; - - if (buffers == NULL) - return BadAlloc; - - if (pDrawable->type == DRAWABLE_WINDOW) { - for (i = 0; i < count; i++) { - /* Do not send the real front buffer of a window to the client. - */ - if (buffers[i]->attachment == DRI2BufferFrontLeft) { - skip++; - continue; - } - } - } - - rep.type = X_Reply; - rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4; - rep.sequenceNumber = client->sequence; - rep.width = width; - rep.height = height; - rep.count = count - skip; - WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); - - for (i = 0; i < count; i++) { - xDRI2Buffer buffer; - - /* Do not send the real front buffer of a window to the client. - */ - if ((pDrawable->type == DRAWABLE_WINDOW) - && (buffers[i]->attachment == DRI2BufferFrontLeft)) { - continue; - } - - buffer.attachment = buffers[i]->attachment; - buffer.name = buffers[i]->name; - buffer.pitch = buffers[i]->pitch; - buffer.cpp = buffers[i]->cpp; - buffer.flags = buffers[i]->flags; - WriteToClient(client, sizeof(xDRI2Buffer), &buffer); - } - return Success; -} - - -static int -ProcDRI2GetBuffers(ClientPtr client) -{ - REQUEST(xDRI2GetBuffersReq); - DrawablePtr pDrawable; - DRI2BufferPtr *buffers; - int status, width, height, count; - unsigned int *attachments; - - REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); - if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, - &pDrawable, &status)) - return status; - - if (DRI2ThrottleClient(client, pDrawable)) - return Success; - - attachments = (unsigned int *) &stuff[1]; - buffers = DRI2GetBuffers(pDrawable, &width, &height, - attachments, stuff->count, &count); - - - return send_buffers_reply(client, pDrawable, buffers, count, width, height); - -} - -static int -ProcDRI2GetBuffersWithFormat(ClientPtr client) -{ - REQUEST(xDRI2GetBuffersReq); - DrawablePtr pDrawable; - DRI2BufferPtr *buffers; - int status, width, height, count; - unsigned int *attachments; - - REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4)); - if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, - &pDrawable, &status)) - return status; - - if (DRI2ThrottleClient(client, pDrawable)) - return Success; - - attachments = (unsigned int *) &stuff[1]; - buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, - attachments, stuff->count, &count); - - return send_buffers_reply(client, pDrawable, buffers, count, width, height); -} - -static int -ProcDRI2CopyRegion(ClientPtr client) -{ - REQUEST(xDRI2CopyRegionReq); - xDRI2CopyRegionReply rep; - DrawablePtr pDrawable; - int status; - RegionPtr pRegion; - - REQUEST_SIZE_MATCH(xDRI2CopyRegionReq); - - if (!validDrawable(client, stuff->drawable, DixWriteAccess, - &pDrawable, &status)) - return status; - - VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); - - status = DRI2CopyRegion(pDrawable, pRegion, stuff->dest, stuff->src); - if (status != Success) - return status; - - /* CopyRegion needs to be a round trip to make sure the X server - * queues the swap buffer rendering commands before the DRI client - * continues rendering. The reply has a bitmask to signal the - * presense of optional return values as well, but we're not using - * that yet. - */ - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep); - - return Success; -} - -static void -load_swap_reply(xDRI2SwapBuffersReply *rep, CARD64 sbc) -{ - rep->swap_hi = sbc >> 32; - rep->swap_lo = sbc & 0xffffffff; -} - -static CARD64 -vals_to_card64(CARD32 lo, CARD32 hi) -{ - return (CARD64)hi << 32 | lo; -} - -static void -DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, - CARD64 sbc) -{ - xDRI2BufferSwapComplete event; - DrawablePtr pDrawable = data; - - event.type = DRI2EventBase + DRI2_BufferSwapComplete; - event.event_type = type; - event.drawable = pDrawable->id; - event.ust_hi = (CARD64)ust >> 32; - event.ust_lo = ust & 0xffffffff; - event.msc_hi = (CARD64)msc >> 32; - event.msc_lo = msc & 0xffffffff; - event.sbc_hi = (CARD64)sbc >> 32; - event.sbc_lo = sbc & 0xffffffff; - - WriteEventsToClient(client, 1, (xEvent *)&event); -} - -static int -ProcDRI2SwapBuffers(ClientPtr client) -{ - REQUEST(xDRI2SwapBuffersReq); - xDRI2SwapBuffersReply rep; - DrawablePtr pDrawable; - CARD64 target_msc, divisor, remainder, swap_target; - int status; - - REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); - - if (!validDrawable(client, stuff->drawable, - DixReadAccess | DixWriteAccess, &pDrawable, &status)) - return status; - - /* - * Ensures an out of control client can't exhaust our swap queue, and - * also orders swaps. - */ - if (DRI2ThrottleClient(client, pDrawable)) - return Success; - - target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi); - divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi); - remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); - - status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder, - &swap_target, DRI2SwapEvent, pDrawable); - if (status != Success) - return BadDrawable; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - load_swap_reply(&rep, swap_target); - - WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep); - - return Success; -} - -static void -load_msc_reply(xDRI2MSCReply *rep, CARD64 ust, CARD64 msc, CARD64 sbc) -{ - rep->ust_hi = ust >> 32; - rep->ust_lo = ust & 0xffffffff; - rep->msc_hi = msc >> 32; - rep->msc_lo = msc & 0xffffffff; - rep->sbc_hi = sbc >> 32; - rep->sbc_lo = sbc & 0xffffffff; -} - -static int -ProcDRI2GetMSC(ClientPtr client) -{ - REQUEST(xDRI2GetMSCReq); - xDRI2MSCReply rep; - DrawablePtr pDrawable; - CARD64 ust, msc, sbc; - int status; - - REQUEST_SIZE_MATCH(xDRI2GetMSCReq); - - if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, - &status)) - return status; - - status = DRI2GetMSC(pDrawable, &ust, &msc, &sbc); - if (status != Success) - return status; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - load_msc_reply(&rep, ust, msc, sbc); - - WriteToClient(client, sizeof(xDRI2MSCReply), &rep); - - return Success; -} - -static int -ProcDRI2WaitMSC(ClientPtr client) -{ - REQUEST(xDRI2WaitMSCReq); - DrawablePtr pDrawable; - CARD64 target, divisor, remainder; - int status; - - /* FIXME: in restart case, client may be gone at this point */ - - REQUEST_SIZE_MATCH(xDRI2WaitMSCReq); - - if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, - &status)) - return status; - - target = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi); - divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi); - remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); - - status = DRI2WaitMSC(client, pDrawable, target, divisor, remainder); - if (status != Success) - return status; - - return Success; -} - -int -ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc) -{ - xDRI2MSCReply rep; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - load_msc_reply(&rep, ust, msc, sbc); - - WriteToClient(client, sizeof(xDRI2MSCReply), &rep); - - return Success; -} - -static int -ProcDRI2SwapInterval(ClientPtr client) -{ - REQUEST(xDRI2SwapIntervalReq); - DrawablePtr pDrawable; - int status; - - /* FIXME: in restart case, client may be gone at this point */ - - REQUEST_SIZE_MATCH(xDRI2SwapIntervalReq); - - if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, - &pDrawable, &status)) - return status; - - DRI2SwapInterval(pDrawable, stuff->interval); - - return Success; -} - -static int -ProcDRI2WaitSBC(ClientPtr client) -{ - REQUEST(xDRI2WaitSBCReq); - DrawablePtr pDrawable; - CARD64 target; - int status; - - REQUEST_SIZE_MATCH(xDRI2WaitSBCReq); - - if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, - &status)) - return status; - - target = vals_to_card64(stuff->target_sbc_lo, stuff->target_sbc_hi); - status = DRI2WaitSBC(client, pDrawable, target); - - return status; -} - -static int -ProcDRI2Dispatch (ClientPtr client) -{ - REQUEST(xReq); - - switch (stuff->data) { - case X_DRI2QueryVersion: - return ProcDRI2QueryVersion(client); - } - - if (!LocalClient(client)) - return BadRequest; - - switch (stuff->data) { - case X_DRI2Connect: - return ProcDRI2Connect(client); - case X_DRI2Authenticate: - return ProcDRI2Authenticate(client); - case X_DRI2CreateDrawable: - return ProcDRI2CreateDrawable(client); - case X_DRI2DestroyDrawable: - return ProcDRI2DestroyDrawable(client); - case X_DRI2GetBuffers: - return ProcDRI2GetBuffers(client); - case X_DRI2CopyRegion: - return ProcDRI2CopyRegion(client); - case X_DRI2GetBuffersWithFormat: - return ProcDRI2GetBuffersWithFormat(client); - case X_DRI2SwapBuffers: - return ProcDRI2SwapBuffers(client); - case X_DRI2GetMSC: - return ProcDRI2GetMSC(client); - case X_DRI2WaitMSC: - return ProcDRI2WaitMSC(client); - case X_DRI2WaitSBC: - return ProcDRI2WaitSBC(client); - case X_DRI2SwapInterval: - return ProcDRI2SwapInterval(client); - default: - return BadRequest; - } -} - -static int -SProcDRI2Connect(ClientPtr client) -{ - REQUEST(xDRI2ConnectReq); - xDRI2ConnectReply rep; - int n; - - /* If the client is swapped, it's not local. Talk to the hand. */ - - swaps(&stuff->length, n); - if (sizeof(*stuff) / 4 != client->req_len) - return BadLength; - - rep.sequenceNumber = client->sequence; - swaps(&rep.sequenceNumber, n); - rep.length = 0; - rep.driverNameLength = 0; - rep.deviceNameLength = 0; - - return Success; -} - -static int -SProcDRI2Dispatch (ClientPtr client) -{ - REQUEST(xReq); - - /* - * Only local clients are allowed DRI access, but remote clients - * still need these requests to find out cleanly. - */ - switch (stuff->data) - { - case X_DRI2QueryVersion: - return ProcDRI2QueryVersion(client); - case X_DRI2Connect: - return SProcDRI2Connect(client); - default: - return BadRequest; - } -} - -int DRI2EventBase; - -static void -DRI2ExtensionInit(void) -{ - dri2Extension = AddExtension(DRI2_NAME, - DRI2NumberEvents, - DRI2NumberErrors, - ProcDRI2Dispatch, - SProcDRI2Dispatch, - NULL, - StandardMinorOpcode); - - DRI2EventBase = dri2Extension->eventBase; -} - -extern Bool noDRI2Extension; - -_X_HIDDEN ExtensionModule dri2ExtensionModule = { - DRI2ExtensionInit, - DRI2_NAME, - &noDRI2Extension, - NULL, - NULL -}; +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "dixstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "extnsionst.h" +#include "xfixes.h" +#include "dri2.h" +#include "protocol-versions.h" + +/* The only xf86 include */ +#include "xf86Module.h" + +static ExtensionEntry *dri2Extension; + +static Bool +validDrawable(ClientPtr client, XID drawable, Mask access_mode, + DrawablePtr *pDrawable, int *status) +{ + *status = dixLookupDrawable(pDrawable, drawable, client, + M_DRAWABLE_WINDOW | M_DRAWABLE_PIXMAP, + access_mode); + if (*status != Success) { + client->errorValue = drawable; + return FALSE; + } + + return TRUE; +} + +static int +ProcDRI2QueryVersion(ClientPtr client) +{ + REQUEST(xDRI2QueryVersionReq); + xDRI2QueryVersionReply rep; + int n; + + if (client->swapped) + swaps(&stuff->length, n); + + REQUEST_SIZE_MATCH(xDRI2QueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = dri2_major; + rep.minorVersion = dri2_minor; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + + WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep); + + return Success; +} + +static int +ProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + DrawablePtr pDraw; + int fd, status; + const char *driverName; + const char *deviceName; + + REQUEST_SIZE_MATCH(xDRI2ConnectReq); + if (!validDrawable(client, stuff->window, DixGetAttrAccess, + &pDraw, &status)) + return status; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.driverNameLength = 0; + rep.deviceNameLength = 0; + + if (!DRI2Connect(pDraw->pScreen, + stuff->driverType, &fd, &driverName, &deviceName)) + goto fail; + + rep.driverNameLength = strlen(driverName); + rep.deviceNameLength = strlen(deviceName); + rep.length = (rep.driverNameLength + 3) / 4 + + (rep.deviceNameLength + 3) / 4; + + fail: + WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); + WriteToClient(client, rep.driverNameLength, driverName); + WriteToClient(client, rep.deviceNameLength, deviceName); + + return Success; +} + +static int +ProcDRI2Authenticate(ClientPtr client) +{ + REQUEST(xDRI2AuthenticateReq); + xDRI2AuthenticateReply rep; + DrawablePtr pDraw; + int status; + + REQUEST_SIZE_MATCH(xDRI2AuthenticateReq); + if (!validDrawable(client, stuff->window, DixGetAttrAccess, + &pDraw, &status)) + return status; + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic); + WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep); + + return Success; +} + +static void +DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv) +{ + xDRI2InvalidateBuffers event; + ClientPtr client = priv; + + event.type = DRI2EventBase + DRI2_InvalidateBuffers; + event.drawable = pDraw->id; + + WriteEventsToClient(client, 1, (xEvent *)&event); +} + +static int +ProcDRI2CreateDrawable(ClientPtr client) +{ + REQUEST(xDRI2CreateDrawableReq); + DrawablePtr pDrawable; + int status; + + REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); + + if (!validDrawable(client, stuff->drawable, DixAddAccess, + &pDrawable, &status)) + return status; + + status = DRI2CreateDrawable(client, pDrawable, stuff->drawable, + DRI2InvalidateBuffersEvent, client); + if (status != Success) + return status; + + return Success; +} + +static int +ProcDRI2DestroyDrawable(ClientPtr client) +{ + REQUEST(xDRI2DestroyDrawableReq); + DrawablePtr pDrawable; + int status; + + REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq); + if (!validDrawable(client, stuff->drawable, DixRemoveAccess, + &pDrawable, &status)) + return status; + + return Success; +} + + +static int +send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, + DRI2BufferPtr *buffers, int count, int width, int height) +{ + xDRI2GetBuffersReply rep; + int skip = 0; + int i; + + if (buffers == NULL) + return BadAlloc; + + if (pDrawable->type == DRAWABLE_WINDOW) { + for (i = 0; i < count; i++) { + /* Do not send the real front buffer of a window to the client. + */ + if (buffers[i]->attachment == DRI2BufferFrontLeft) { + skip++; + continue; + } + } + } + + rep.type = X_Reply; + rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4; + rep.sequenceNumber = client->sequence; + rep.width = width; + rep.height = height; + rep.count = count - skip; + WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); + + for (i = 0; i < count; i++) { + xDRI2Buffer buffer; + + /* Do not send the real front buffer of a window to the client. + */ + if ((pDrawable->type == DRAWABLE_WINDOW) + && (buffers[i]->attachment == DRI2BufferFrontLeft)) { + continue; + } + + buffer.attachment = buffers[i]->attachment; + buffer.name = buffers[i]->name; + buffer.pitch = buffers[i]->pitch; + buffer.cpp = buffers[i]->cpp; + buffer.flags = buffers[i]->flags; + WriteToClient(client, sizeof(xDRI2Buffer), &buffer); + } + return Success; +} + + +static int +ProcDRI2GetBuffers(ClientPtr client) +{ + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2BufferPtr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); + if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, + &pDrawable, &status)) + return status; + + if (DRI2ThrottleClient(client, pDrawable)) + return Success; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffers(pDrawable, &width, &height, + attachments, stuff->count, &count); + + + return send_buffers_reply(client, pDrawable, buffers, count, width, height); + +} + +static int +ProcDRI2GetBuffersWithFormat(ClientPtr client) +{ + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2BufferPtr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4)); + if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, + &pDrawable, &status)) + return status; + + if (DRI2ThrottleClient(client, pDrawable)) + return Success; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, + attachments, stuff->count, &count); + + return send_buffers_reply(client, pDrawable, buffers, count, width, height); +} + +static int +ProcDRI2CopyRegion(ClientPtr client) +{ + REQUEST(xDRI2CopyRegionReq); + xDRI2CopyRegionReply rep; + DrawablePtr pDrawable; + int status; + RegionPtr pRegion; + + REQUEST_SIZE_MATCH(xDRI2CopyRegionReq); + + if (!validDrawable(client, stuff->drawable, DixWriteAccess, + &pDrawable, &status)) + return status; + + VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); + + status = DRI2CopyRegion(pDrawable, pRegion, stuff->dest, stuff->src); + if (status != Success) + return status; + + /* CopyRegion needs to be a round trip to make sure the X server + * queues the swap buffer rendering commands before the DRI client + * continues rendering. The reply has a bitmask to signal the + * presense of optional return values as well, but we're not using + * that yet. + */ + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep); + + return Success; +} + +static void +load_swap_reply(xDRI2SwapBuffersReply *rep, CARD64 sbc) +{ + rep->swap_hi = sbc >> 32; + rep->swap_lo = sbc & 0xffffffff; +} + +static CARD64 +vals_to_card64(CARD32 lo, CARD32 hi) +{ + return (CARD64)hi << 32 | lo; +} + +static void +DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, + CARD32 sbc) +{ + xDRI2BufferSwapComplete2 event; + DrawablePtr pDrawable = data; + + event.type = DRI2EventBase + DRI2_BufferSwapComplete; + event.event_type = type; + event.drawable = pDrawable->id; + event.ust_hi = (CARD64)ust >> 32; + event.ust_lo = ust & 0xffffffff; + event.msc_hi = (CARD64)msc >> 32; + event.msc_lo = msc & 0xffffffff; + event.sbc = sbc; + + WriteEventsToClient(client, 1, (xEvent *)&event); +} + +static int +ProcDRI2SwapBuffers(ClientPtr client) +{ + REQUEST(xDRI2SwapBuffersReq); + xDRI2SwapBuffersReply rep; + DrawablePtr pDrawable; + CARD64 target_msc, divisor, remainder, swap_target; + int status; + + REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); + + if (!validDrawable(client, stuff->drawable, + DixReadAccess | DixWriteAccess, &pDrawable, &status)) + return status; + + /* + * Ensures an out of control client can't exhaust our swap queue, and + * also orders swaps. + */ + if (DRI2ThrottleClient(client, pDrawable)) + return Success; + + target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi); + divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi); + remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); + + status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder, + &swap_target, DRI2SwapEvent, pDrawable); + if (status != Success) + return BadDrawable; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + load_swap_reply(&rep, swap_target); + + WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep); + + return Success; +} + +static void +load_msc_reply(xDRI2MSCReply *rep, CARD64 ust, CARD64 msc, CARD64 sbc) +{ + rep->ust_hi = ust >> 32; + rep->ust_lo = ust & 0xffffffff; + rep->msc_hi = msc >> 32; + rep->msc_lo = msc & 0xffffffff; + rep->sbc_hi = sbc >> 32; + rep->sbc_lo = sbc & 0xffffffff; +} + +static int +ProcDRI2GetMSC(ClientPtr client) +{ + REQUEST(xDRI2GetMSCReq); + xDRI2MSCReply rep; + DrawablePtr pDrawable; + CARD64 ust, msc, sbc; + int status; + + REQUEST_SIZE_MATCH(xDRI2GetMSCReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, + &status)) + return status; + + status = DRI2GetMSC(pDrawable, &ust, &msc, &sbc); + if (status != Success) + return status; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + load_msc_reply(&rep, ust, msc, sbc); + + WriteToClient(client, sizeof(xDRI2MSCReply), &rep); + + return Success; +} + +static int +ProcDRI2WaitMSC(ClientPtr client) +{ + REQUEST(xDRI2WaitMSCReq); + DrawablePtr pDrawable; + CARD64 target, divisor, remainder; + int status; + + /* FIXME: in restart case, client may be gone at this point */ + + REQUEST_SIZE_MATCH(xDRI2WaitMSCReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, + &status)) + return status; + + target = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi); + divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi); + remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); + + status = DRI2WaitMSC(client, pDrawable, target, divisor, remainder); + if (status != Success) + return status; + + return Success; +} + +int +ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc) +{ + xDRI2MSCReply rep; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + load_msc_reply(&rep, ust, msc, sbc); + + WriteToClient(client, sizeof(xDRI2MSCReply), &rep); + + return Success; +} + +static int +ProcDRI2SwapInterval(ClientPtr client) +{ + REQUEST(xDRI2SwapIntervalReq); + DrawablePtr pDrawable; + int status; + + /* FIXME: in restart case, client may be gone at this point */ + + REQUEST_SIZE_MATCH(xDRI2SwapIntervalReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, + &pDrawable, &status)) + return status; + + DRI2SwapInterval(pDrawable, stuff->interval); + + return Success; +} + +static int +ProcDRI2WaitSBC(ClientPtr client) +{ + REQUEST(xDRI2WaitSBCReq); + DrawablePtr pDrawable; + CARD64 target; + int status; + + REQUEST_SIZE_MATCH(xDRI2WaitSBCReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, + &status)) + return status; + + target = vals_to_card64(stuff->target_sbc_lo, stuff->target_sbc_hi); + status = DRI2WaitSBC(client, pDrawable, target); + + return status; +} + +static int +ProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + } + + if (!LocalClient(client)) + return BadRequest; + + switch (stuff->data) { + case X_DRI2Connect: + return ProcDRI2Connect(client); + case X_DRI2Authenticate: + return ProcDRI2Authenticate(client); + case X_DRI2CreateDrawable: + return ProcDRI2CreateDrawable(client); + case X_DRI2DestroyDrawable: + return ProcDRI2DestroyDrawable(client); + case X_DRI2GetBuffers: + return ProcDRI2GetBuffers(client); + case X_DRI2CopyRegion: + return ProcDRI2CopyRegion(client); + case X_DRI2GetBuffersWithFormat: + return ProcDRI2GetBuffersWithFormat(client); + case X_DRI2SwapBuffers: + return ProcDRI2SwapBuffers(client); + case X_DRI2GetMSC: + return ProcDRI2GetMSC(client); + case X_DRI2WaitMSC: + return ProcDRI2WaitMSC(client); + case X_DRI2WaitSBC: + return ProcDRI2WaitSBC(client); + case X_DRI2SwapInterval: + return ProcDRI2SwapInterval(client); + default: + return BadRequest; + } +} + +static int +SProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + int n; + + /* If the client is swapped, it's not local. Talk to the hand. */ + + swaps(&stuff->length, n); + if (sizeof(*stuff) / 4 != client->req_len) + return BadLength; + + rep.sequenceNumber = client->sequence; + swaps(&rep.sequenceNumber, n); + rep.length = 0; + rep.driverNameLength = 0; + rep.deviceNameLength = 0; + + return Success; +} + +static int +SProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + /* + * Only local clients are allowed DRI access, but remote clients + * still need these requests to find out cleanly. + */ + switch (stuff->data) + { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + case X_DRI2Connect: + return SProcDRI2Connect(client); + default: + return BadRequest; + } +} + +int DRI2EventBase; + +static void +DRI2ExtensionInit(void) +{ + dri2Extension = AddExtension(DRI2_NAME, + DRI2NumberEvents, + DRI2NumberErrors, + ProcDRI2Dispatch, + SProcDRI2Dispatch, + NULL, + StandardMinorOpcode); + + DRI2EventBase = dri2Extension->eventBase; +} + +extern Bool noDRI2Extension; + +_X_HIDDEN ExtensionModule dri2ExtensionModule = { + DRI2ExtensionInit, + DRI2_NAME, + &noDRI2Extension, + NULL, + NULL +}; -- cgit v1.2.3