summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-05-04 10:35:13 +0100
committerDave Airlie <airlied@redhat.com>2012-05-04 10:35:13 +0100
commitf55cc4048b96bee102eb184023520648ac3690fc (patch)
treeeeeea0c27d20438e9d27abfedb05e0dd1027aeab
parent69fc7f94fdc9348597841c280e06e4bd711b2a06 (diff)
randr: port over provider code from v2
-rw-r--r--randr/Makefile.am1
-rw-r--r--randr/randr.c5
-rw-r--r--randr/randrstr.h50
-rw-r--r--randr/rrdispatch.c8
-rw-r--r--randr/rrprovider.c260
5 files changed, 324 insertions, 0 deletions
diff --git a/randr/Makefile.am b/randr/Makefile.am
index de338b972..b8019d45d 100644
--- a/randr/Makefile.am
+++ b/randr/Makefile.am
@@ -18,6 +18,7 @@ librandr_la_SOURCES = \
rroutput.c \
rrpointer.c \
rrproperty.c \
+ rrprovider.c \
rrscreen.c \
rrsdispatch.c \
rrtransform.h \
diff --git a/randr/randr.c b/randr/randr.c
index a64aae366..28dd76196 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -93,9 +93,12 @@ RRCloseScreen(ScreenPtr pScreen)
RRCrtcDestroy(pScrPriv->crtcs[j]);
for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
RROutputDestroy(pScrPriv->outputs[j]);
+ for (j = pScrPriv->numProviders - 1; j >= 0; j--)
+ RRProviderDestroy(pScrPriv->providers[j]);
free(pScrPriv->crtcs);
free(pScrPriv->outputs);
+ free(pScrPriv->providers);
free(pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
return (*pScreen->CloseScreen) (pScreen);
@@ -208,6 +211,8 @@ RRInit(void)
return FALSE;
if (!RROutputInit())
return FALSE;
+ if (!RRProviderInit())
+ return FALSE;
RRGeneration = serverGeneration;
}
if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0))
diff --git a/randr/randrstr.h b/randr/randrstr.h
index f75fe44ce..3d038a6b3 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -62,6 +62,7 @@
typedef XID RRMode;
typedef XID RROutput;
typedef XID RRCrtc;
+typedef XID RRProvider;
extern _X_EXPORT int RREventBase, RRErrorBase;
@@ -78,6 +79,7 @@ typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr;
typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
typedef struct _rrOutput RROutputRec, *RROutputPtr;
+typedef struct _rrProvider RRProviderRec, *RRProviderPtr;
struct _rrMode {
int refcnt;
@@ -152,6 +154,14 @@ struct _rrOutput {
void *devPrivate;
};
+struct _rrProvider {
+ RRProvider id;
+ ScreenPtr pScreen; /* gpu screen more than likely */
+ int current_role;
+ int allowed_roles;
+ void *devPrivate;
+};
+
#if RANDR_12_INTERFACE
typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
CARD16 width,
@@ -197,6 +207,10 @@ typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn,
#endif /* RANDR_13_INTERFACE */
+typedef Bool (*RRProviderSetRoleProcPtr)(ScreenPtr pScreen,
+ RRProviderPtr provider,
+ int new_role);
+
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations);
typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen);
@@ -246,6 +260,7 @@ typedef struct _rrScrPriv {
RRGetPanningProcPtr rrGetPanning;
RRSetPanningProcPtr rrSetPanning;
#endif
+ RRProviderSetRoleProcPtr rrProviderSetRole;
/*
* Private part of the structure; not considered part of the ABI
@@ -288,6 +303,9 @@ typedef struct _rrScrPriv {
int size;
#endif
Bool discontiguous;
+
+ int numProviders;
+ RRProviderPtr *providers;
} rrScrPrivRec, *rrScrPrivPtr;
extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
@@ -363,6 +381,16 @@ extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType;
}\
}
+#define VERIFY_RR_PROVIDER(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+ RRProviderType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+
#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey))
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
@@ -843,6 +871,28 @@ extern _X_EXPORT int
extern _X_EXPORT int
ProcRRDeleteOutputProperty(ClientPtr client);
+/* rrprovider.c */
+extern _X_EXPORT int
+ProcRRGetProviders(ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetProviderInfo(ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRSetProviderRole(ClientPtr client);
+
+extern _X_EXPORT Bool
+RRProviderInit(void);
+
+extern _X_EXPORT RRProviderPtr
+RRProviderCreate(ScreenPtr pScreen, void *devPrivate);
+
+extern _X_EXPORT void
+RRProviderDestroy (RRProviderPtr provider);
+
+extern _X_EXPORT Bool
+RRProviderLookup(XID id, RRProviderPtr *provider_p);
+
/* rrxinerama.c */
#ifdef XINERAMA
extern _X_EXPORT void
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index 85cf03738..501d25720 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -241,4 +241,12 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
ProcRRSetPanning, /* 29 */
ProcRRSetOutputPrimary, /* 30 */
ProcRRGetOutputPrimary, /* 31 */
+ NULL, /* 32 */
+ NULL, /* 33 */
+ NULL, /* 34 */
+ NULL, /* 35 */
+ NULL, /* 36 */
+ ProcRRGetProviders, /* 37 */
+ ProcRRGetProviderInfo, /* 38 */
+ ProcRRSetProviderRole, /* 39 */
};
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
new file mode 100644
index 000000000..3907bcae3
--- /dev/null
+++ b/randr/rrprovider.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+
+RESTYPE RRProviderType;
+
+int
+ProcRRGetProviders (ClientPtr client)
+{
+ REQUEST(xRRGetProvidersReq);
+ xRRGetProvidersReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ int rc;
+ CARD8 *extra;
+ unsigned int extraLen;
+ RRProvider *providers;
+ int i;
+
+ REQUEST_SIZE_MATCH(xRRGetProvidersReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ rep.pad = 0;
+
+ if (!pScrPriv)
+ {
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.timestamp = currentTime.milliseconds;
+ rep.nProviders = 0;
+ extra = NULL;
+ extraLen = 0;
+ } else {
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.length = 0;
+ rep.nProviders = pScrPriv->numProviders;
+
+ rep.length = pScrPriv->numProviders;
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = malloc(extraLen);
+ if (!extra)
+ return BadAlloc;
+ } else
+ extra = NULL;
+
+ providers = (RRProvider *)extra;
+ for (i = 0; i < pScrPriv->numProviders; i++) {
+ providers[i] = pScrPriv->providers[i]->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ }
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swaps(&rep.nProviders);
+ }
+ WriteToClient(client, sizeof(xRRGetProvidersReply), (char *)&rep);
+ if (extraLen)
+ {
+ WriteToClient (client, extraLen, (char *) extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRGetProviderInfo (ClientPtr client)
+{
+ REQUEST(xRRGetProviderInfoReq);
+ xRRGetProviderInfoReply rep;
+ rrScrPrivPtr pScrPriv;
+ RRProviderPtr provider;
+ ScreenPtr pScreen;
+ CARD8 *extra;
+ unsigned int extraLen = 0;
+
+ REQUEST_SIZE_MATCH(xRRGetProviderInfoReq);
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ rep.type = X_Reply;
+ rep.status = RRSetConfigSuccess;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.current_role = provider->current_role;
+ rep.allowed_roles = provider->allowed_roles;
+ if (rep.current_role > 0) {
+ // rep.nCrtcs = provider->numCrtcs;
+ // rep.nOutputs = provider->numOutputs;
+ } else {
+ rep.nCrtcs = 0;
+ rep.nOutputs = 0;
+ }
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.current_role);
+ swapl(&rep.allowed_roles);
+ swaps(&rep.nCrtcs);
+ swaps(&rep.nOutputs);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderInfoReply), (char *)&rep);
+ if (extraLen)
+ {
+ WriteToClient (client, extraLen, (char *) extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRSetProviderRole (ClientPtr client)
+{
+ REQUEST(xRRSetProviderRoleReq);
+ rrScrPrivPtr pScrPriv;
+ RRProviderPtr provider;
+ ScreenPtr pScreen;
+ Bool ret;
+ REQUEST_SIZE_MATCH(xRRSetProviderRoleReq);
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (stuff->new_role) {
+ if (!(stuff->new_role & provider->allowed_roles))
+ return BadValue;
+
+ if (stuff->new_role == provider->current_role)
+ return Success;
+ }
+
+ ret = pScrPriv->rrProviderSetRole(pScreen, provider, stuff->new_role);
+
+ RRTellChanged (pScreen);
+ return Success;
+}
+
+RRProviderPtr
+RRProviderCreate(ScreenPtr pScreen, void *devPrivate)
+{
+ RRProviderPtr provider;
+ RRProviderPtr *providers;
+ rrScrPrivPtr pScrPriv;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ /* make space for the crtc pointer */
+ if (pScrPriv->numProviders)
+ providers = realloc(pScrPriv->providers,
+ (pScrPriv->numProviders + 1) * sizeof (RRProviderPtr));
+ else
+ providers = malloc(sizeof (RRProviderPtr));
+ if (!providers)
+ return NULL;
+ pScrPriv->providers = providers;
+
+ provider = calloc(1, sizeof(RRProviderRec));
+ if (!provider)
+ return NULL;
+
+ provider->id = FakeClientID(0);
+ provider->pScreen = pScreen;
+ provider->devPrivate = devPrivate;
+ if (!AddResource (provider->id, RRProviderType, (pointer) provider))
+ return NULL;
+ pScrPriv->providers[pScrPriv->numProviders++] = provider;
+ return provider;
+}
+
+/*
+ * Destroy a provider at shutdown
+ */
+void
+RRProviderDestroy (RRProviderPtr provider)
+{
+ FreeResource (provider->id, 0);
+}
+
+static int
+RRProviderDestroyResource (pointer value, XID pid)
+{
+ RRProviderPtr provider = (RRProviderPtr)value;
+ ScreenPtr pScreen = provider->pScreen;
+
+ if (pScreen)
+ {
+ rrScrPriv(pScreen);
+ int i;
+
+ for (i = 0; i < pScrPriv->numProviders; i++)
+ {
+ if (pScrPriv->providers[i] == provider)
+ {
+ memmove (pScrPriv->providers + i, pScrPriv->providers + i + 1,
+ (pScrPriv->numProviders - (i + 1)) * sizeof (RRProviderPtr));
+ --pScrPriv->numProviders;
+ break;
+ }
+ }
+ }
+ free(provider);
+ return 1;
+}
+
+Bool
+RRProviderInit(void)
+{
+ RRProviderType = CreateNewResourceType(RRProviderDestroyResource, "Provider");
+ if (!RRProviderType)
+ return FALSE;
+
+ return TRUE;
+}
+
+extern _X_EXPORT Bool
+RRProviderLookup(XID id, RRProviderPtr *provider_p)
+{
+ RRProviderPtr provider;
+ int rc = dixLookupResourceByType((void **)provider_p, id,
+ RRProviderType, NullClient, DixReadAccess);
+ if (rc == Success)
+ return TRUE;
+ return FALSE;
+}