105b261ecSmrg/************************************************************************** 205b261ecSmrg 305b261ecSmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 405b261ecSmrgCopyright 2000 VA Linux Systems, Inc. 505b261ecSmrgAll Rights Reserved. 605b261ecSmrg 705b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a 805b261ecSmrgcopy of this software and associated documentation files (the 905b261ecSmrg"Software"), to deal in the Software without restriction, including 1005b261ecSmrgwithout limitation the rights to use, copy, modify, merge, publish, 1105b261ecSmrgdistribute, sub license, and/or sell copies of the Software, and to 1205b261ecSmrgpermit persons to whom the Software is furnished to do so, subject to 1305b261ecSmrgthe following conditions: 1405b261ecSmrg 1505b261ecSmrgThe above copyright notice and this permission notice (including the 1605b261ecSmrgnext paragraph) shall be included in all copies or substantial portions 1705b261ecSmrgof the Software. 1805b261ecSmrg 1905b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2005b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2105b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2205b261ecSmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 2305b261ecSmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2405b261ecSmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2505b261ecSmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2605b261ecSmrg 2705b261ecSmrg**************************************************************************/ 2805b261ecSmrg 2905b261ecSmrg/* 3005b261ecSmrg * Authors: 3105b261ecSmrg * Kevin E. Martin <martin@valinux.com> 3205b261ecSmrg * Jens Owen <jens@tungstengraphics.com> 3305b261ecSmrg * Rickard E. (Rik) Faith <faith@valinux.com> 3405b261ecSmrg * 3505b261ecSmrg */ 3605b261ecSmrg 3705b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 3805b261ecSmrg#include <xorg-config.h> 3905b261ecSmrg#endif 4005b261ecSmrg 4105b261ecSmrg#include <string.h> 4205b261ecSmrg 4305b261ecSmrg#include "xf86.h" 4405b261ecSmrg 4505b261ecSmrg#include <X11/X.h> 4605b261ecSmrg#include <X11/Xproto.h> 4705b261ecSmrg#include "misc.h" 4805b261ecSmrg#include "dixstruct.h" 4905b261ecSmrg#include "extnsionst.h" 5035c4bbdfSmrg#include "extinit.h" 5105b261ecSmrg#include "colormapst.h" 5205b261ecSmrg#include "cursorstr.h" 5305b261ecSmrg#include "scrnintstr.h" 5405b261ecSmrg#include "servermd.h" 5505b261ecSmrg#define _XF86DRI_SERVER_ 566747b715Smrg#include <X11/dri/xf86driproto.h> 5705b261ecSmrg#include "swaprep.h" 5805b261ecSmrg#include "xf86str.h" 5905b261ecSmrg#include "dri.h" 6005b261ecSmrg#include "sarea.h" 6105b261ecSmrg#include "dristruct.h" 6205b261ecSmrg#include "xf86drm.h" 636747b715Smrg#include "protocol-versions.h" 6435c4bbdfSmrg#include "xf86Extensions.h" 6505b261ecSmrg 6605b261ecSmrgstatic int DRIErrorBase; 6705b261ecSmrg 6835c4bbdfSmrgstatic void XF86DRIResetProc(ExtensionEntry *extEntry); 6905b261ecSmrg 7005b261ecSmrgstatic unsigned char DRIReqCode = 0; 7105b261ecSmrg 7205b261ecSmrg/*ARGSUSED*/ 7305b261ecSmrgstatic void 7435c4bbdfSmrgXF86DRIResetProc(ExtensionEntry *extEntry) 7505b261ecSmrg{ 7605b261ecSmrg DRIReset(); 7705b261ecSmrg} 7805b261ecSmrg 7905b261ecSmrgstatic int 8035c4bbdfSmrgProcXF86DRIQueryVersion(register ClientPtr client) 8105b261ecSmrg{ 8235c4bbdfSmrg xXF86DRIQueryVersionReply rep = { 8335c4bbdfSmrg .type = X_Reply, 8435c4bbdfSmrg .sequenceNumber = client->sequence, 8535c4bbdfSmrg .length = 0, 8635c4bbdfSmrg .majorVersion = SERVER_XF86DRI_MAJOR_VERSION, 8735c4bbdfSmrg .minorVersion = SERVER_XF86DRI_MINOR_VERSION, 8835c4bbdfSmrg .patchVersion = SERVER_XF86DRI_PATCH_VERSION 8935c4bbdfSmrg }; 9005b261ecSmrg 9105b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq); 9205b261ecSmrg if (client->swapped) { 9335c4bbdfSmrg swaps(&rep.sequenceNumber); 9435c4bbdfSmrg swapl(&rep.length); 9535c4bbdfSmrg swaps(&rep.majorVersion); 9635c4bbdfSmrg swaps(&rep.minorVersion); 9735c4bbdfSmrg swapl(&rep.patchVersion); 9805b261ecSmrg } 9935c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), &rep); 1006747b715Smrg return Success; 10105b261ecSmrg} 10205b261ecSmrg 10305b261ecSmrgstatic int 10435c4bbdfSmrgProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client) 10505b261ecSmrg{ 10635c4bbdfSmrg xXF86DRIQueryDirectRenderingCapableReply rep; 10705b261ecSmrg Bool isCapable; 10805b261ecSmrg 10905b261ecSmrg REQUEST(xXF86DRIQueryDirectRenderingCapableReq); 11005b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); 11105b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 11235c4bbdfSmrg client->errorValue = stuff->screen; 11335c4bbdfSmrg return BadValue; 11405b261ecSmrg } 11505b261ecSmrg 11635c4bbdfSmrg if (!DRIQueryDirectRenderingCapable(screenInfo.screens[stuff->screen], 11735c4bbdfSmrg &isCapable)) { 11835c4bbdfSmrg return BadValue; 11905b261ecSmrg } 12005b261ecSmrg 12135c4bbdfSmrg if (!client->local || client->swapped) 12235c4bbdfSmrg isCapable = 0; 12335c4bbdfSmrg 12435c4bbdfSmrg rep = (xXF86DRIQueryDirectRenderingCapableReply) { 12535c4bbdfSmrg .type = X_Reply, 12635c4bbdfSmrg .sequenceNumber = client->sequence, 12735c4bbdfSmrg .length = 0, 12835c4bbdfSmrg .isCapable = isCapable 12935c4bbdfSmrg }; 13005b261ecSmrg 13105b261ecSmrg if (client->swapped) { 13235c4bbdfSmrg swaps(&rep.sequenceNumber); 13335c4bbdfSmrg swapl(&rep.length); 13405b261ecSmrg } 13505b261ecSmrg 13635c4bbdfSmrg WriteToClient(client, 13735c4bbdfSmrg sizeof(xXF86DRIQueryDirectRenderingCapableReply), 13835c4bbdfSmrg &rep); 1396747b715Smrg return Success; 14005b261ecSmrg} 14105b261ecSmrg 14205b261ecSmrgstatic int 14335c4bbdfSmrgProcXF86DRIOpenConnection(register ClientPtr client) 14405b261ecSmrg{ 14505b261ecSmrg xXF86DRIOpenConnectionReply rep; 14635c4bbdfSmrg drm_handle_t hSAREA; 14735c4bbdfSmrg char *busIdString; 14835c4bbdfSmrg CARD32 busIdStringLength = 0; 14905b261ecSmrg 15005b261ecSmrg REQUEST(xXF86DRIOpenConnectionReq); 15105b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq); 15205b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 15335c4bbdfSmrg client->errorValue = stuff->screen; 15435c4bbdfSmrg return BadValue; 15505b261ecSmrg } 15605b261ecSmrg 15735c4bbdfSmrg if (!DRIOpenConnection(screenInfo.screens[stuff->screen], 15835c4bbdfSmrg &hSAREA, &busIdString)) { 15935c4bbdfSmrg return BadValue; 16005b261ecSmrg } 16105b261ecSmrg 16205b261ecSmrg if (busIdString) 16335c4bbdfSmrg busIdStringLength = strlen(busIdString); 16405b261ecSmrg 16535c4bbdfSmrg rep = (xXF86DRIOpenConnectionReply) { 16635c4bbdfSmrg .type = X_Reply, 16735c4bbdfSmrg .sequenceNumber = client->sequence, 16835c4bbdfSmrg .length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - 16935c4bbdfSmrg SIZEOF(xGenericReply) + 17035c4bbdfSmrg pad_to_int32(busIdStringLength)), 17135c4bbdfSmrg .busIdStringLength = busIdStringLength, 17235c4bbdfSmrg 17335c4bbdfSmrg .hSAREALow = (CARD32) (hSAREA & 0xffffffff), 17405b261ecSmrg#if defined(LONG64) && !defined(__linux__) 17535c4bbdfSmrg .hSAREAHigh = (CARD32) (hSAREA >> 32), 17605b261ecSmrg#else 17735c4bbdfSmrg .hSAREAHigh = 0 17805b261ecSmrg#endif 17935c4bbdfSmrg }; 18005b261ecSmrg 18135c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), &rep); 18235c4bbdfSmrg if (busIdStringLength) 18335c4bbdfSmrg WriteToClient(client, busIdStringLength, busIdString); 1846747b715Smrg return Success; 18505b261ecSmrg} 18605b261ecSmrg 18705b261ecSmrgstatic int 18835c4bbdfSmrgProcXF86DRIAuthConnection(register ClientPtr client) 18905b261ecSmrg{ 19035c4bbdfSmrg xXF86DRIAuthConnectionReply rep = { 19135c4bbdfSmrg .type = X_Reply, 19235c4bbdfSmrg .sequenceNumber = client->sequence, 19335c4bbdfSmrg .length = 0, 19435c4bbdfSmrg .authenticated = 1 19535c4bbdfSmrg }; 19635c4bbdfSmrg 19705b261ecSmrg REQUEST(xXF86DRIAuthConnectionReq); 19805b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq); 19905b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 20035c4bbdfSmrg client->errorValue = stuff->screen; 20135c4bbdfSmrg return BadValue; 20205b261ecSmrg } 20305b261ecSmrg 20435c4bbdfSmrg if (!DRIAuthConnection(screenInfo.screens[stuff->screen], stuff->magic)) { 20535c4bbdfSmrg ErrorF("Failed to authenticate %lu\n", (unsigned long) stuff->magic); 20635c4bbdfSmrg rep.authenticated = 0; 20705b261ecSmrg } 20835c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), &rep); 2096747b715Smrg return Success; 21005b261ecSmrg} 21105b261ecSmrg 21205b261ecSmrgstatic int 21335c4bbdfSmrgProcXF86DRICloseConnection(register ClientPtr client) 21405b261ecSmrg{ 21505b261ecSmrg REQUEST(xXF86DRICloseConnectionReq); 21605b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq); 21705b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 21835c4bbdfSmrg client->errorValue = stuff->screen; 21935c4bbdfSmrg return BadValue; 22005b261ecSmrg } 22105b261ecSmrg 22235c4bbdfSmrg DRICloseConnection(screenInfo.screens[stuff->screen]); 22305b261ecSmrg 2246747b715Smrg return Success; 22505b261ecSmrg} 22605b261ecSmrg 22705b261ecSmrgstatic int 22835c4bbdfSmrgProcXF86DRIGetClientDriverName(register ClientPtr client) 22905b261ecSmrg{ 23035c4bbdfSmrg xXF86DRIGetClientDriverNameReply rep = { 23135c4bbdfSmrg .type = X_Reply, 23235c4bbdfSmrg .sequenceNumber = client->sequence, 23335c4bbdfSmrg .clientDriverNameLength = 0 23435c4bbdfSmrg }; 23535c4bbdfSmrg char *clientDriverName; 23605b261ecSmrg 23705b261ecSmrg REQUEST(xXF86DRIGetClientDriverNameReq); 23805b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq); 23905b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 24035c4bbdfSmrg client->errorValue = stuff->screen; 24135c4bbdfSmrg return BadValue; 24205b261ecSmrg } 24305b261ecSmrg 24435c4bbdfSmrg DRIGetClientDriverName(screenInfo.screens[stuff->screen], 24535c4bbdfSmrg (int *) &rep.ddxDriverMajorVersion, 24635c4bbdfSmrg (int *) &rep.ddxDriverMinorVersion, 24735c4bbdfSmrg (int *) &rep.ddxDriverPatchVersion, 24835c4bbdfSmrg &clientDriverName); 24905b261ecSmrg 25005b261ecSmrg if (clientDriverName) 25135c4bbdfSmrg rep.clientDriverNameLength = strlen(clientDriverName); 2526747b715Smrg rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) - 25335c4bbdfSmrg SIZEOF(xGenericReply) + 25435c4bbdfSmrg pad_to_int32(rep.clientDriverNameLength)); 25505b261ecSmrg 25635c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRIGetClientDriverNameReply), &rep); 25705b261ecSmrg if (rep.clientDriverNameLength) 25835c4bbdfSmrg WriteToClient(client, rep.clientDriverNameLength, clientDriverName); 2596747b715Smrg return Success; 26005b261ecSmrg} 26105b261ecSmrg 26205b261ecSmrgstatic int 26335c4bbdfSmrgProcXF86DRICreateContext(register ClientPtr client) 26405b261ecSmrg{ 26535c4bbdfSmrg xXF86DRICreateContextReply rep = { 26635c4bbdfSmrg .type = X_Reply, 26735c4bbdfSmrg .sequenceNumber = client->sequence, 26835c4bbdfSmrg .length = 0 26935c4bbdfSmrg }; 27005b261ecSmrg ScreenPtr pScreen; 27105b261ecSmrg 27205b261ecSmrg REQUEST(xXF86DRICreateContextReq); 27305b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRICreateContextReq); 27405b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 27535c4bbdfSmrg client->errorValue = stuff->screen; 27635c4bbdfSmrg return BadValue; 27705b261ecSmrg } 27805b261ecSmrg 27905b261ecSmrg pScreen = screenInfo.screens[stuff->screen]; 28005b261ecSmrg 28135c4bbdfSmrg if (!DRICreateContext(pScreen, 28235c4bbdfSmrg NULL, 28335c4bbdfSmrg stuff->context, (drm_context_t *) &rep.hHWContext)) { 28435c4bbdfSmrg return BadValue; 28505b261ecSmrg } 28605b261ecSmrg 28735c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRICreateContextReply), &rep); 2886747b715Smrg return Success; 28905b261ecSmrg} 29005b261ecSmrg 29105b261ecSmrgstatic int 29235c4bbdfSmrgProcXF86DRIDestroyContext(register ClientPtr client) 29305b261ecSmrg{ 29405b261ecSmrg REQUEST(xXF86DRIDestroyContextReq); 29505b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq); 29605b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 29735c4bbdfSmrg client->errorValue = stuff->screen; 29835c4bbdfSmrg return BadValue; 29905b261ecSmrg } 30005b261ecSmrg 30135c4bbdfSmrg if (!DRIDestroyContext(screenInfo.screens[stuff->screen], stuff->context)) { 30235c4bbdfSmrg return BadValue; 30305b261ecSmrg } 30405b261ecSmrg 3056747b715Smrg return Success; 30605b261ecSmrg} 30705b261ecSmrg 30805b261ecSmrgstatic int 30935c4bbdfSmrgProcXF86DRICreateDrawable(ClientPtr client) 31005b261ecSmrg{ 31135c4bbdfSmrg xXF86DRICreateDrawableReply rep = { 31235c4bbdfSmrg .type = X_Reply, 31335c4bbdfSmrg .sequenceNumber = client->sequence, 31435c4bbdfSmrg .length = 0 31535c4bbdfSmrg }; 31605b261ecSmrg DrawablePtr pDrawable; 31705b261ecSmrg int rc; 31805b261ecSmrg 31905b261ecSmrg REQUEST(xXF86DRICreateDrawableReq); 32005b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq); 32105b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 32235c4bbdfSmrg client->errorValue = stuff->screen; 32335c4bbdfSmrg return BadValue; 32405b261ecSmrg } 32505b261ecSmrg 32605b261ecSmrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 32735c4bbdfSmrg DixReadAccess); 32805b261ecSmrg if (rc != Success) 32935c4bbdfSmrg return rc; 33005b261ecSmrg 33105b261ecSmrg if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client, 33235c4bbdfSmrg pDrawable, (drm_drawable_t *) &rep.hHWDrawable)) { 33335c4bbdfSmrg return BadValue; 33405b261ecSmrg } 33505b261ecSmrg 33635c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), &rep); 3376747b715Smrg return Success; 33805b261ecSmrg} 33905b261ecSmrg 34005b261ecSmrgstatic int 34135c4bbdfSmrgProcXF86DRIDestroyDrawable(register ClientPtr client) 34205b261ecSmrg{ 34305b261ecSmrg REQUEST(xXF86DRIDestroyDrawableReq); 34405b261ecSmrg DrawablePtr pDrawable; 34505b261ecSmrg int rc; 34635c4bbdfSmrg 3476747b715Smrg REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq); 34805b261ecSmrg 34905b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 35035c4bbdfSmrg client->errorValue = stuff->screen; 35135c4bbdfSmrg return BadValue; 35205b261ecSmrg } 35305b261ecSmrg 35405b261ecSmrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 35535c4bbdfSmrg DixReadAccess); 35605b261ecSmrg if (rc != Success) 35735c4bbdfSmrg return rc; 35805b261ecSmrg 35905b261ecSmrg if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client, 36035c4bbdfSmrg pDrawable)) { 36135c4bbdfSmrg return BadValue; 36205b261ecSmrg } 36305b261ecSmrg 3646747b715Smrg return Success; 36505b261ecSmrg} 36605b261ecSmrg 36705b261ecSmrgstatic int 36835c4bbdfSmrgProcXF86DRIGetDrawableInfo(register ClientPtr client) 36905b261ecSmrg{ 37035c4bbdfSmrg xXF86DRIGetDrawableInfoReply rep = { 37135c4bbdfSmrg .type = X_Reply, 37235c4bbdfSmrg .sequenceNumber = client->sequence, 37335c4bbdfSmrg .length = 0 37435c4bbdfSmrg }; 37505b261ecSmrg DrawablePtr pDrawable; 37605b261ecSmrg int X, Y, W, H; 37735c4bbdfSmrg drm_clip_rect_t *pClipRects, *pClippedRects; 37835c4bbdfSmrg drm_clip_rect_t *pBackClipRects; 37905b261ecSmrg int backX, backY, rc; 38005b261ecSmrg 38105b261ecSmrg REQUEST(xXF86DRIGetDrawableInfoReq); 38205b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq); 38305b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 38435c4bbdfSmrg client->errorValue = stuff->screen; 38535c4bbdfSmrg return BadValue; 38605b261ecSmrg } 38705b261ecSmrg 38805b261ecSmrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 38935c4bbdfSmrg DixReadAccess); 39005b261ecSmrg if (rc != Success) 39135c4bbdfSmrg return rc; 39235c4bbdfSmrg 39335c4bbdfSmrg if (!DRIGetDrawableInfo(screenInfo.screens[stuff->screen], 39435c4bbdfSmrg pDrawable, 39535c4bbdfSmrg (unsigned int *) &rep.drawableTableIndex, 39635c4bbdfSmrg (unsigned int *) &rep.drawableTableStamp, 39735c4bbdfSmrg (int *) &X, 39835c4bbdfSmrg (int *) &Y, 39935c4bbdfSmrg (int *) &W, 40035c4bbdfSmrg (int *) &H, 40135c4bbdfSmrg (int *) &rep.numClipRects, 40235c4bbdfSmrg &pClipRects, 40335c4bbdfSmrg &backX, 40435c4bbdfSmrg &backY, 40535c4bbdfSmrg (int *) &rep.numBackClipRects, &pBackClipRects)) { 40635c4bbdfSmrg return BadValue; 40705b261ecSmrg } 40805b261ecSmrg 40905b261ecSmrg rep.drawableX = X; 41005b261ecSmrg rep.drawableY = Y; 41105b261ecSmrg rep.drawableWidth = W; 41205b261ecSmrg rep.drawableHeight = H; 41335c4bbdfSmrg rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - SIZEOF(xGenericReply)); 41405b261ecSmrg 41505b261ecSmrg rep.backX = backX; 41605b261ecSmrg rep.backY = backY; 41735c4bbdfSmrg 41835c4bbdfSmrg if (rep.numBackClipRects) 41935c4bbdfSmrg rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects; 42005b261ecSmrg 42105b261ecSmrg pClippedRects = pClipRects; 42205b261ecSmrg 42305b261ecSmrg if (rep.numClipRects) { 42435c4bbdfSmrg /* Clip cliprects to screen dimensions (redirected windows) */ 42535c4bbdfSmrg pClippedRects = xallocarray(rep.numClipRects, sizeof(drm_clip_rect_t)); 42635c4bbdfSmrg 42735c4bbdfSmrg if (pClippedRects) { 42835c4bbdfSmrg ScreenPtr pScreen = screenInfo.screens[stuff->screen]; 42935c4bbdfSmrg int i, j; 43035c4bbdfSmrg 43135c4bbdfSmrg for (i = 0, j = 0; i < rep.numClipRects; i++) { 43235c4bbdfSmrg pClippedRects[j].x1 = max(pClipRects[i].x1, 0); 43335c4bbdfSmrg pClippedRects[j].y1 = max(pClipRects[i].y1, 0); 43435c4bbdfSmrg pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width); 43535c4bbdfSmrg pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height); 43635c4bbdfSmrg 43735c4bbdfSmrg if (pClippedRects[j].x1 < pClippedRects[j].x2 && 43835c4bbdfSmrg pClippedRects[j].y1 < pClippedRects[j].y2) { 43935c4bbdfSmrg j++; 44035c4bbdfSmrg } 44135c4bbdfSmrg } 44235c4bbdfSmrg 44335c4bbdfSmrg rep.numClipRects = j; 44435c4bbdfSmrg } 44535c4bbdfSmrg else { 44635c4bbdfSmrg rep.numClipRects = 0; 44735c4bbdfSmrg } 44835c4bbdfSmrg 44935c4bbdfSmrg rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects; 45005b261ecSmrg } 45135c4bbdfSmrg 4526747b715Smrg rep.length = bytes_to_int32(rep.length); 45305b261ecSmrg 45435c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), &rep); 45505b261ecSmrg 45605b261ecSmrg if (rep.numClipRects) { 45735c4bbdfSmrg WriteToClient(client, 45835c4bbdfSmrg sizeof(drm_clip_rect_t) * rep.numClipRects, 45935c4bbdfSmrg pClippedRects); 46035c4bbdfSmrg free(pClippedRects); 46105b261ecSmrg } 46205b261ecSmrg 46305b261ecSmrg if (rep.numBackClipRects) { 46435c4bbdfSmrg WriteToClient(client, 46535c4bbdfSmrg sizeof(drm_clip_rect_t) * rep.numBackClipRects, 46635c4bbdfSmrg pBackClipRects); 46705b261ecSmrg } 46805b261ecSmrg 4696747b715Smrg return Success; 47005b261ecSmrg} 47105b261ecSmrg 47205b261ecSmrgstatic int 47335c4bbdfSmrgProcXF86DRIGetDeviceInfo(register ClientPtr client) 47405b261ecSmrg{ 47535c4bbdfSmrg xXF86DRIGetDeviceInfoReply rep = { 47635c4bbdfSmrg .type = X_Reply, 47735c4bbdfSmrg .sequenceNumber = client->sequence, 47835c4bbdfSmrg .length = 0 47935c4bbdfSmrg }; 48005b261ecSmrg drm_handle_t hFrameBuffer; 48105b261ecSmrg void *pDevPrivate; 48205b261ecSmrg 48305b261ecSmrg REQUEST(xXF86DRIGetDeviceInfoReq); 48405b261ecSmrg REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq); 48505b261ecSmrg if (stuff->screen >= screenInfo.numScreens) { 48635c4bbdfSmrg client->errorValue = stuff->screen; 48735c4bbdfSmrg return BadValue; 48805b261ecSmrg } 48905b261ecSmrg 49035c4bbdfSmrg if (!DRIGetDeviceInfo(screenInfo.screens[stuff->screen], 49135c4bbdfSmrg &hFrameBuffer, 49235c4bbdfSmrg (int *) &rep.framebufferOrigin, 49335c4bbdfSmrg (int *) &rep.framebufferSize, 49435c4bbdfSmrg (int *) &rep.framebufferStride, 49535c4bbdfSmrg (int *) &rep.devPrivateSize, &pDevPrivate)) { 49635c4bbdfSmrg return BadValue; 49705b261ecSmrg } 49805b261ecSmrg 49935c4bbdfSmrg rep.hFrameBufferLow = (CARD32) (hFrameBuffer & 0xffffffff); 50005b261ecSmrg#if defined(LONG64) && !defined(__linux__) 50135c4bbdfSmrg rep.hFrameBufferHigh = (CARD32) (hFrameBuffer >> 32); 50205b261ecSmrg#else 50305b261ecSmrg rep.hFrameBufferHigh = 0; 50405b261ecSmrg#endif 50505b261ecSmrg 50605b261ecSmrg if (rep.devPrivateSize) { 50735c4bbdfSmrg rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) - 50835c4bbdfSmrg SIZEOF(xGenericReply) + 50935c4bbdfSmrg pad_to_int32(rep.devPrivateSize)); 51005b261ecSmrg } 51105b261ecSmrg 51235c4bbdfSmrg WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), &rep); 51305b261ecSmrg if (rep.length) { 51435c4bbdfSmrg WriteToClient(client, rep.devPrivateSize, pDevPrivate); 51505b261ecSmrg } 5166747b715Smrg return Success; 51705b261ecSmrg} 51805b261ecSmrg 51905b261ecSmrgstatic int 52035c4bbdfSmrgProcXF86DRIDispatch(register ClientPtr client) 52105b261ecSmrg{ 52205b261ecSmrg REQUEST(xReq); 52305b261ecSmrg 52435c4bbdfSmrg switch (stuff->data) { 52505b261ecSmrg case X_XF86DRIQueryVersion: 52635c4bbdfSmrg return ProcXF86DRIQueryVersion(client); 52705b261ecSmrg case X_XF86DRIQueryDirectRenderingCapable: 52835c4bbdfSmrg return ProcXF86DRIQueryDirectRenderingCapable(client); 52905b261ecSmrg } 53005b261ecSmrg 53135c4bbdfSmrg if (!client->local) 53235c4bbdfSmrg return DRIErrorBase + XF86DRIClientNotLocal; 53305b261ecSmrg 53435c4bbdfSmrg switch (stuff->data) { 53505b261ecSmrg case X_XF86DRIOpenConnection: 53635c4bbdfSmrg return ProcXF86DRIOpenConnection(client); 53705b261ecSmrg case X_XF86DRICloseConnection: 53835c4bbdfSmrg return ProcXF86DRICloseConnection(client); 53905b261ecSmrg case X_XF86DRIGetClientDriverName: 54035c4bbdfSmrg return ProcXF86DRIGetClientDriverName(client); 54105b261ecSmrg case X_XF86DRICreateContext: 54235c4bbdfSmrg return ProcXF86DRICreateContext(client); 54305b261ecSmrg case X_XF86DRIDestroyContext: 54435c4bbdfSmrg return ProcXF86DRIDestroyContext(client); 54505b261ecSmrg case X_XF86DRICreateDrawable: 54635c4bbdfSmrg return ProcXF86DRICreateDrawable(client); 54705b261ecSmrg case X_XF86DRIDestroyDrawable: 54835c4bbdfSmrg return ProcXF86DRIDestroyDrawable(client); 54905b261ecSmrg case X_XF86DRIGetDrawableInfo: 55035c4bbdfSmrg return ProcXF86DRIGetDrawableInfo(client); 55105b261ecSmrg case X_XF86DRIGetDeviceInfo: 55235c4bbdfSmrg return ProcXF86DRIGetDeviceInfo(client); 55305b261ecSmrg case X_XF86DRIAuthConnection: 55435c4bbdfSmrg return ProcXF86DRIAuthConnection(client); 55535c4bbdfSmrg /* {Open,Close}FullScreen are deprecated now */ 55605b261ecSmrg default: 55735c4bbdfSmrg return BadRequest; 55805b261ecSmrg } 55905b261ecSmrg} 56005b261ecSmrg 5617e31ba66Smrgstatic int _X_COLD 56235c4bbdfSmrgSProcXF86DRIQueryVersion(register ClientPtr client) 56305b261ecSmrg{ 56405b261ecSmrg REQUEST(xXF86DRIQueryVersionReq); 56535c4bbdfSmrg swaps(&stuff->length); 56605b261ecSmrg return ProcXF86DRIQueryVersion(client); 56705b261ecSmrg} 56805b261ecSmrg 5697e31ba66Smrgstatic int _X_COLD 57035c4bbdfSmrgSProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client) 57105b261ecSmrg{ 57205b261ecSmrg REQUEST(xXF86DRIQueryDirectRenderingCapableReq); 5736e78d31fSmrg REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); 57435c4bbdfSmrg swaps(&stuff->length); 57535c4bbdfSmrg swapl(&stuff->screen); 57605b261ecSmrg return ProcXF86DRIQueryDirectRenderingCapable(client); 57705b261ecSmrg} 57805b261ecSmrg 5797e31ba66Smrgstatic int _X_COLD 58035c4bbdfSmrgSProcXF86DRIDispatch(register ClientPtr client) 58105b261ecSmrg{ 58205b261ecSmrg REQUEST(xReq); 58305b261ecSmrg 58405b261ecSmrg /* 58505b261ecSmrg * Only local clients are allowed DRI access, but remote clients still need 58605b261ecSmrg * these requests to find out cleanly. 58705b261ecSmrg */ 58835c4bbdfSmrg switch (stuff->data) { 58905b261ecSmrg case X_XF86DRIQueryVersion: 59035c4bbdfSmrg return SProcXF86DRIQueryVersion(client); 59105b261ecSmrg case X_XF86DRIQueryDirectRenderingCapable: 59235c4bbdfSmrg return SProcXF86DRIQueryDirectRenderingCapable(client); 59305b261ecSmrg default: 59435c4bbdfSmrg return DRIErrorBase + XF86DRIClientNotLocal; 59505b261ecSmrg } 59605b261ecSmrg} 5979ace9065Smrg 5989ace9065Smrgvoid 5999ace9065SmrgXFree86DRIExtensionInit(void) 6009ace9065Smrg{ 60135c4bbdfSmrg ExtensionEntry *extEntry; 6029ace9065Smrg 60335c4bbdfSmrg if (DRIExtensionInit() && 60435c4bbdfSmrg (extEntry = AddExtension(XF86DRINAME, 60535c4bbdfSmrg XF86DRINumberEvents, 60635c4bbdfSmrg XF86DRINumberErrors, 60735c4bbdfSmrg ProcXF86DRIDispatch, 60835c4bbdfSmrg SProcXF86DRIDispatch, 60935c4bbdfSmrg XF86DRIResetProc, StandardMinorOpcode))) { 61035c4bbdfSmrg DRIReqCode = (unsigned char) extEntry->base; 61135c4bbdfSmrg DRIErrorBase = extEntry->errorBase; 6129ace9065Smrg } 6139ace9065Smrg} 614