From 06f081eac8f7762cec8fb352d0897b3699a48ca5 Mon Sep 17 00:00:00 2001 From: Alban Browaeys Date: Fri, 27 Aug 2010 03:00:54 +0200 Subject: [PATCH] dri2: add callbacks to handle driver events state. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is added fields, functions and a global for to implement a partial option3 as defined in http://lists.x.org/archives/xorg-driver-ati/2010-August/016780.html by Oldřich Jedlička and Christopher James Halse Rogers. Partial in that I do not normalize events to move them into the dri2 layer. I merely provide callbacks to maange event state and a common code to handle the list of event. --- hw/xfree86/dri2/dri2.h | 15 ++++++++ hw/xfree86/dri2/dri2ext.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 0 deletions(-) diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index fe0bf6c..c7649c8 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -34,6 +34,7 @@ #define _DRI2_H_ #include +#include "list.h" /* Version 2 structure (with format at the end) */ typedef struct { @@ -46,6 +47,13 @@ typedef struct { void *driverPrivate; } DRI2BufferRec, *DRI2BufferPtr; +typedef struct _DRI2FrameEventBase { + void *driverEvent; + struct list link; +} DRI2FrameEventBaseRec, *DRI2FrameEventBasePtr; + + + extern CARD8 dri2_major; /* version of DRI2 supported by DDX */ extern CARD8 dri2_minor; @@ -158,6 +166,7 @@ typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client, typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw, void *data); +typedef void (*DRI2InvalidateEntryProcPtr)(DRI2FrameEventBasePtr entry); /** * Version of the DRI2InfoRec structure defined in this header */ @@ -189,9 +198,11 @@ typedef struct { /* added in version 5 */ DRI2AuthMagicProcPtr AuthMagic; + } DRI2InfoRec, *DRI2InfoPtr; extern _X_EXPORT int DRI2EventBase; +extern _X_EXPORT DRI2InvalidateEntryProcPtr InvalidateDRI2ClientEntry; extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info); @@ -284,4 +295,8 @@ extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame, unsigned int tv_sec, unsigned int tv_usec); + +extern _X_EXPORT Bool ListAddDRI2ClientEntry(ClientPtr client, struct list *entry); +extern _X_EXPORT void ListDelDRI2ClientEntry(ClientPtr client, struct list *entry); + #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index 4e48e65..1077b9a 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -49,6 +49,9 @@ /* The only xf86 include */ #include "xf86Module.h" + +#include "xf86.h" + static ExtensionEntry *dri2Extension; static Bool @@ -625,9 +628,92 @@ SProcDRI2Dispatch (ClientPtr client) int DRI2EventBase; +#if DRI2INFOREC_VERSION >= 4 + +DRI2InvalidateEntryProcPtr InvalidateDRI2ClientEntry; + +typedef struct _DRI2ClientEvents { + struct list reference_list; +} DRI2ClientEventsRec, *DRI2ClientEventsPtr; + +static DevPrivateKeyRec DRI2ClientEventsPrivateKeyRec; +#define DRI2ClientEventsPrivateKey (&DRI2ClientEventsPrivateKeyRec) + +#define GetDRI2ClientEvents(_pClient) (DRI2ClientEventsPtr) \ + dixLookupPrivate(&(_pClient)->devPrivates, DRI2ClientEventsPrivateKey) + + +static void +DRI2ClientCallback(CallbackListPtr *ClientStateCallback, pointer closure, pointer calldata) +{ + + DRI2ClientEventsPtr pClientEventsPriv; + DRI2FrameEventBasePtr ref; + NewClientInfoRec *clientinfo = calldata; + ClientPtr pClient = clientinfo->client; + pClientEventsPriv = GetDRI2ClientEvents(pClient); + + switch (pClient->clientState) { + case ClientStateInitial: + list_init(&pClientEventsPriv->reference_list); + break; + case ClientStateRunning: + break; + + case ClientStateRetained: + case ClientStateGone: + if (pClientEventsPriv) { + list_for_each_entry(ref, &pClientEventsPriv->reference_list, link) { + InvalidateDRI2ClientEntry(ref); + } + } + break; + default: + break; + } +} + +Bool +ListAddDRI2ClientEntry(ClientPtr client, struct list *entry) +{ + DRI2ClientEventsPtr pClientPriv; + pClientPriv = GetDRI2ClientEvents(client); + + if (!pClientPriv) { + return FALSE; + } + + list_add(entry, &pClientPriv->reference_list); + return TRUE; +} + + +void +ListDelDRI2ClientEntry(ClientPtr client, struct list *entry) +{ + DRI2ClientEventsPtr pClientPriv; + pClientPriv = GetDRI2ClientEvents(client); + + if (!pClientPriv) { + return; + } + list_del(entry); +} +#endif + static void DRI2ExtensionInit(void) { +#if DRI2INFOREC_VERSION >= 4 + if (!dixRegisterPrivateKey(DRI2ClientEventsPrivateKey, PRIVATE_CLIENT, sizeof(DRI2ClientEventsRec))) { + xf86Msg(X_WARNING, "DRI2 registering private key to client failed\n"); + return; + } + if (!AddCallback(&ClientStateCallback, DRI2ClientCallback, 0)) { + xf86Msg(X_WARNING, "DRI2 registering client callback failed\n"); + return; + } +#endif dri2Extension = AddExtension(DRI2_NAME, DRI2NumberEvents, DRI2NumberErrors, -- 1.7.1