[PATCH v2 xserver] xwayland: Don't roundtrip in DRI2 authentication mechanism
Tiago Vignatti
tiago.vignatti at intel.com
Mon Feb 4 08:54:59 PST 2013
Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
v2: - added AuthMagic3, for passing ClientPtr
- fixed server internal ABI issue, by maintaining DRI2Authenticate intact
- fixed multiple clients accesses to DRI2 authenticate, using Wayland
callback mechanism to ensure they all go atomically
hw/xfree86/dri2/dri2.c | 16 ++++++++++--
hw/xfree86/dri2/dri2.h | 12 ++++++---
hw/xfree86/dri2/dri2ext.c | 45 +++++++++++++++++++++++++++++++--
hw/xfree86/xwayland/xwayland-drm.c | 49 +++++++++++++++++++++++++++++-------
hw/xfree86/xwayland/xwayland.h | 2 +-
5 files changed, 107 insertions(+), 17 deletions(-)
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index b08618a..54efeae 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -107,6 +107,7 @@ typedef struct _DRI2Screen {
DRI2GetMSCProcPtr GetMSC;
DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
DRI2AuthMagic2ProcPtr AuthMagic;
+ DRI2AuthMagic3ProcPtr AuthMagic3;
DRI2AuthMagicProcPtr LegacyAuthMagic;
DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify;
DRI2SwapLimitValidateProcPtr SwapLimitValidate;
@@ -1133,6 +1134,17 @@ DRI2Authenticate(ScreenPtr pScreen, uint32_t magic)
return TRUE;
}
+Bool
+DRI2XWaylandAuthenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ if (ds == NULL || (*ds->AuthMagic3) (client, pScreen, magic))
+ return FALSE;
+
+ return TRUE;
+}
+
static int
DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
WindowPtr pSib)
@@ -1222,10 +1234,10 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
*
* If a driver is built without xwayland support, we'll die before we get
* here. If a driver is built with xwayland support, it'll support
- * AuthMagic2, or crash; we don't care about xwayland ABI yet.
+ * AuthMagic3, or crash; we don't care about xwayland ABI yet.
*/
if (xorgWayland) {
- ds->AuthMagic = info->AuthMagic2;
+ ds->AuthMagic3 = info->AuthMagic3;
}
if (info->version >= 5) {
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index cec9634..1323cd7 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -65,6 +65,8 @@ typedef void (*DRI2CopyRegionProcPtr) (DrawablePtr pDraw,
typedef void (*DRI2WaitProcPtr) (WindowPtr pWin, unsigned int sequence);
typedef int (*DRI2AuthMagicProcPtr) (int fd, uint32_t magic);
typedef int (*DRI2AuthMagic2ProcPtr) (ScreenPtr pScreen, uint32_t magic);
+typedef int (*DRI2AuthMagic3ProcPtr) (ClientPtr client,
+ ScreenPtr pScreen, uint32_t magic);
/**
* Schedule a buffer swap
@@ -219,9 +221,7 @@ typedef struct {
* is unnecessary, but it's slightly different in master.
*/
/* AuthMagic callback which passes extra context */
- /* If this is NULL the AuthMagic callback is used */
- /* If this is non-NULL the AuthMagic callback is ignored */
- DRI2AuthMagic2ProcPtr AuthMagic2;
+ DRI2AuthMagic3ProcPtr AuthMagic3;
} DRI2InfoRec, *DRI2InfoPtr;
extern _X_EXPORT int DRI2EventBase;
@@ -240,6 +240,12 @@ extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic);
+extern _X_EXPORT void DRI2SendAuthReply(ClientPtr client, int status);
+
+extern _X_EXPORT Bool DRI2XWaylandAuthenticate(ClientPtr client,
+ ScreenPtr pScreen,
+ uint32_t magic);
+
extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
DrawablePtr pDraw,
XID id,
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 2579a5c..30add45 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -46,8 +46,8 @@
#include "dri2.h"
#include "protocol-versions.h"
-/* The only xf86 include */
#include "xf86Module.h"
+#include "xf86Priv.h" /* xorgWayland */
static ExtensionEntry *dri2Extension;
extern Bool DRI2ModuleSetup(void);
@@ -155,6 +155,44 @@ ProcDRI2Authenticate(ClientPtr client)
return Success;
}
+void
+DRI2SendAuthReply(ClientPtr client, int status)
+{
+ xDRI2AuthenticateReply rep;
+
+ REQUEST_SIZE_MATCH(xDRI2AuthenticateReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.authenticated = status;
+
+ WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
+
+ if (client->ignoreCount > 0)
+ AttendClient(client);
+}
+
+static int
+ProcDRI2XWaylandAuthenticate(ClientPtr client)
+{
+ REQUEST(xDRI2AuthenticateReq);
+ DrawablePtr pDraw;
+ int status;
+
+ if (!validDrawable(client, stuff->window, DixGetAttrAccess,
+ &pDraw, &status))
+ return status;
+
+ if (DRI2XWaylandAuthenticate(client, pDraw->pScreen, stuff->magic)) {
+ IgnoreClient(client);
+ return Success;
+ }
+
+ /* BadAccess or BadDrawable */
+ DRI2SendAuthReply(client, status);
+ return Success;
+}
+
static void
DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id)
{
@@ -551,7 +589,10 @@ ProcDRI2Dispatch(ClientPtr client)
case X_DRI2Connect:
return ProcDRI2Connect(client);
case X_DRI2Authenticate:
- return ProcDRI2Authenticate(client);
+ if (xorgWayland)
+ return ProcDRI2XWaylandAuthenticate(client);
+ else
+ return ProcDRI2Authenticate(client);
case X_DRI2CreateDrawable:
return ProcDRI2CreateDrawable(client);
case X_DRI2DestroyDrawable:
diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
index c19eb84..5dd4af4 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -45,6 +45,7 @@
#include "xwayland.h"
#include "xwayland-private.h"
+#include "../dri2/dri2.h"
static void
drm_handle_device (void *data, struct wl_drm *drm, const char *device)
@@ -143,22 +144,52 @@ int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
return xwl_screen->drm_fd;
}
-int xwl_drm_authenticate(struct xwl_screen *xwl_screen,
- uint32_t magic)
+static DevPrivateKeyRec xwl_client_private_key;
+
+static void
+sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
{
- int ret;
+ ClientPtr client = data;
+ struct xwl_screen *xwl_screen;
+ int status;
+
+ xwl_screen =
+ dixLookupPrivate(&client->devPrivates, &xwl_client_private_key);
+
+ if (xwl_screen->authenticated)
+ status = Success;
+ else
+ status = BadAccess;
+
+ DRI2SendAuthReply(client, status);
xwl_screen->authenticated = 0;
+ wl_callback_destroy(callback);
+}
- if (xwl_screen->drm)
- wl_drm_authenticate (xwl_screen->drm, magic);
+static const struct wl_callback_listener sync_listener = {
+ sync_callback
+};
- ret = wl_display_roundtrip(xwl_screen->display);
- if (ret == -1)
- return BadAlloc;
- if (!xwl_screen->authenticated)
+int xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
+ uint32_t magic)
+{
+ struct wl_callback *callback;
+
+ if (!xwl_screen->drm)
+ return BadAccess;
+
+ if (!dixRegisterPrivateKey(&xwl_client_private_key, PRIVATE_CLIENT, 0))
return BadAlloc;
+ dixSetPrivate(&client->devPrivates, &xwl_client_private_key, xwl_screen);
+
+ xwl_screen->authenticated = 0;
+
+ wl_drm_authenticate (xwl_screen->drm, magic);
+ callback = wl_display_sync(xwl_screen->display);
+ wl_callback_add_listener(callback, &sync_listener, client);
+
return Success;
}
diff --git a/hw/xfree86/xwayland/xwayland.h b/hw/xfree86/xwayland/xwayland.h
index e536c42..f268366 100644
--- a/hw/xfree86/xwayland/xwayland.h
+++ b/hw/xfree86/xwayland/xwayland.h
@@ -69,7 +69,7 @@ extern _X_EXPORT void
xwl_screen_post_damage(struct xwl_screen *xwl_screen);
extern _X_EXPORT int
-xwl_drm_authenticate(struct xwl_screen *xwl_screen,
+xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
uint32_t magic);
extern _X_EXPORT int
--
1.7.9.5
More information about the wayland-devel
mailing list