diff options
Diffstat (limited to 'xorg-server/hw/xfree86/dri2/dri2ext.c')
-rw-r--r-- | xorg-server/hw/xfree86/dri2/dri2ext.c | 234 |
1 files changed, 152 insertions, 82 deletions
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c index 4ae0fda3a..3c06174cb 100644 --- a/xorg-server/hw/xfree86/dri2/dri2ext.c +++ b/xorg-server/hw/xfree86/dri2/dri2ext.c @@ -38,11 +38,13 @@ #include <X11/X.h> #include <X11/Xproto.h> #include <X11/extensions/dri2proto.h> +#include <X11/extensions/xfixeswire.h> #include "dixstruct.h" #include "scrnintstr.h" #include "pixmapstr.h" #include "extnsionst.h" #include "xf86drm.h" +#include "xfixes.h" #include "dri2.h" /* The only xf86 include */ @@ -52,19 +54,6 @@ static ExtensionEntry *dri2Extension; static RESTYPE dri2DrawableRes; static Bool -validScreen(ClientPtr client, int screen, ScreenPtr *pScreen) -{ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return FALSE; - } - - *pScreen = screenInfo.screens[screen]; - - return TRUE; -} - -static Bool validDrawable(ClientPtr client, XID drawable, DrawablePtr *pDrawable, int *status) { @@ -91,8 +80,8 @@ ProcDRI2QueryVersion(ClientPtr client) rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; - rep.majorVersion = DRI2_MAJOR; - rep.minorVersion = DRI2_MINOR; + rep.majorVersion = 1; + rep.minorVersion = 1; if (client->swapped) { swaps(&rep.sequenceNumber, n); @@ -111,67 +100,55 @@ ProcDRI2Connect(ClientPtr client) { REQUEST(xDRI2ConnectReq); xDRI2ConnectReply rep; - ScreenPtr pScreen; - int fd; + DrawablePtr pDraw; + int fd, status; const char *driverName; - char *busId = NULL; - unsigned int sareaHandle; + const char *deviceName; REQUEST_SIZE_MATCH(xDRI2ConnectReq); - if (!validScreen(client, stuff->screen, &pScreen)) - return BadValue; + if (!validDrawable(client, stuff->window, &pDraw, &status)) + return status; rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; rep.driverNameLength = 0; - rep.busIdLength = 0; - rep.sareaHandle = 0; - - if (!DRI2Connect(pScreen, &fd, &driverName, &sareaHandle)) - goto fail; + rep.deviceNameLength = 0; - busId = drmGetBusid(fd); - if (busId == NULL) + if (!DRI2Connect(pDraw->pScreen, + stuff->driverType, &fd, &driverName, &deviceName)) goto fail; rep.driverNameLength = strlen(driverName); - rep.busIdLength = strlen(busId); - rep.sareaHandle = sareaHandle; - rep.length = (rep.driverNameLength + 3) / 4 + (rep.busIdLength + 3) / 4; + 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.busIdLength, busId); - drmFreeBusid(busId); + WriteToClient(client, rep.deviceNameLength, deviceName); return client->noClientException; } static int -ProcDRI2AuthConnection(ClientPtr client) +ProcDRI2Authenticate(ClientPtr client) { - REQUEST(xDRI2AuthConnectionReq); - xDRI2AuthConnectionReply rep; - ScreenPtr pScreen; + REQUEST(xDRI2AuthenticateReq); + xDRI2AuthenticateReply rep; + DrawablePtr pDraw; + int status; - REQUEST_SIZE_MATCH(xDRI2AuthConnectionReq); - if (!validScreen(client, stuff->screen, &pScreen)) - return BadValue; + REQUEST_SIZE_MATCH(xDRI2AuthenticateReq); + if (!validDrawable(client, stuff->window, &pDraw, &status)) + return status; rep.type = X_Reply; - rep.length = 0; rep.sequenceNumber = client->sequence; - rep.authenticated = 1; - - if (!DRI2AuthConnection(pScreen, stuff->magic)) { - ErrorF("DRI2: Failed to authenticate %lu\n", - (unsigned long) stuff->magic); - rep.authenticated = 0; - } - - WriteToClient(client, sizeof(xDRI2AuthConnectionReply), &rep); + rep.length = 0; + rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic); + WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep); return client->noClientException; } @@ -180,9 +157,7 @@ static int ProcDRI2CreateDrawable(ClientPtr client) { REQUEST(xDRI2CreateDrawableReq); - xDRI2CreateDrawableReply rep; DrawablePtr pDrawable; - unsigned int handle, head; int status; REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); @@ -190,22 +165,15 @@ ProcDRI2CreateDrawable(ClientPtr client) if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) return status; - if (!DRI2CreateDrawable(pDrawable, &handle, &head)) - return BadMatch; + status = DRI2CreateDrawable(pDrawable); + if (status != Success) + return status; if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) { DRI2DestroyDrawable(pDrawable); return BadAlloc; } - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.handle = handle; - rep.head = head; - - WriteToClient(client, sizeof(xDRI2CreateDrawableReply), &rep); - return client->noClientException; } @@ -225,27 +193,131 @@ ProcDRI2DestroyDrawable(ClientPtr client) return client->noClientException; } + +static void +send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, + DRI2Buffer2Ptr *buffers, int count, int width, int height) +{ + xDRI2GetBuffersReply rep; + int skip = 0; + int i; + + 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); + } +} + + +static int +ProcDRI2GetBuffers(ClientPtr client) +{ + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2Buffer2Ptr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffers(pDrawable, &width, &height, + attachments, stuff->count, &count); + + + send_buffers_reply(client, pDrawable, buffers, count, width, height); + + return client->noClientException; +} + static int -ProcDRI2ReemitDrawableInfo(ClientPtr client) +ProcDRI2GetBuffersWithFormat(ClientPtr client) { - REQUEST(xDRI2ReemitDrawableInfoReq); - xDRI2ReemitDrawableInfoReply rep; + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2Buffer2Ptr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4)); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, + attachments, stuff->count, &count); + + send_buffers_reply(client, pDrawable, buffers, count, width, height); + + return client->noClientException; +} + +static int +ProcDRI2CopyRegion(ClientPtr client) +{ + REQUEST(xDRI2CopyRegionReq); + xDRI2CopyRegionReply rep; DrawablePtr pDrawable; - unsigned int head; int status; + RegionPtr pRegion; + + REQUEST_SIZE_MATCH(xDRI2CopyRegionReq); - REQUEST_SIZE_MATCH(xDRI2ReemitDrawableInfoReq); if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) return status; - DRI2ReemitDrawableInfo(pDrawable, &head); + 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; - rep.head = head; - WriteToClient(client, sizeof(xDRI2ReemitDrawableInfoReply), &rep); + WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep); return client->noClientException; } @@ -266,14 +338,18 @@ ProcDRI2Dispatch (ClientPtr client) switch (stuff->data) { case X_DRI2Connect: return ProcDRI2Connect(client); - case X_DRI2AuthConnection: - return ProcDRI2AuthConnection(client); + case X_DRI2Authenticate: + return ProcDRI2Authenticate(client); case X_DRI2CreateDrawable: return ProcDRI2CreateDrawable(client); case X_DRI2DestroyDrawable: return ProcDRI2DestroyDrawable(client); - case X_DRI2ReemitDrawableInfo: - return ProcDRI2ReemitDrawableInfo(client); + case X_DRI2GetBuffers: + return ProcDRI2GetBuffers(client); + case X_DRI2CopyRegion: + return ProcDRI2CopyRegion(client); + case X_DRI2GetBuffersWithFormat: + return ProcDRI2GetBuffersWithFormat(client); default: return BadRequest; } @@ -296,8 +372,7 @@ SProcDRI2Connect(ClientPtr client) swaps(&rep.sequenceNumber, n); rep.length = 0; rep.driverNameLength = 0; - rep.busIdLength = 0; - rep.sareaHandle = 0; + rep.deviceNameLength = 0; return client->noClientException; } @@ -322,11 +397,6 @@ SProcDRI2Dispatch (ClientPtr client) } } -static void -DRI2ResetProc (ExtensionEntry *extEntry) -{ -} - static int DRI2DrawableGone(pointer p, XID id) { DrawablePtr pDrawable = p; @@ -344,7 +414,7 @@ DRI2ExtensionInit(void) DRI2NumberErrors, ProcDRI2Dispatch, SProcDRI2Dispatch, - DRI2ResetProc, + NULL, StandardMinorOpcode); dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone); |