aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/dri2/dri2ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/dri2/dri2ext.c')
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c234
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);