summaryrefslogtreecommitdiff
path: root/randr/rrprovider.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-06-13 14:03:04 +0100
committerDave Airlie <airlied@redhat.com>2012-07-06 22:16:02 +0100
commit66d92afeaeed9f4a19267d95a1f81b9bf27162a5 (patch)
treedb48a29abbf6e4470b528f36c130a26aabc52bd1 /randr/rrprovider.c
parent44eae69f1df2d00e0c9f1ea8d3c4fae06bcacfbc (diff)
randr: add provider object and provider property support (v6)
This adds the initial provider object and provider property support to the randr dix code. v2: destroy provider in screen close v2.1: fix whitespace v3: update for latest rev of protocol + renumber after 1.4 tearout. v4: fix logic issue, thanks Samsagax on irc v5: keithp's review: fix current_role, fix copyrights, fix master reporting crtc/outputs. v6: port to new randr interface, drop all set role bits for now v7: drop devPrivate in provider, not needed, add BadMatch returns for NULL SetProviderOffloadSink and SetProviderOutputSource, drop the old typedef. Reviewed-by: Keith Packard <keithp@keithp.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'randr/rrprovider.c')
-rw-r--r--randr/rrprovider.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
new file mode 100644
index 000000000..db7074c40
--- /dev/null
+++ b/randr/rrprovider.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright © 2012 Red Hat Inc.
+ *
+ * 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.
+ *
+ * Authors: Dave Airlie
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+
+RESTYPE RRProviderType;
+
+/*
+ * Initialize provider type error value
+ */
+void
+RRProviderInitErrorValue(void)
+{
+ SetResourceTypeErrorValue(RRProviderType, RRErrorBase + BadRRProvider);
+}
+
+#define ADD_PROVIDER(_pScreen) do { \
+ pScrPriv = rrGetScrPriv((_pScreen)); \
+ if (pScrPriv->provider) { \
+ providers[count_providers] = pScrPriv->provider->id; \
+ if (client->swapped) \
+ swapl(&providers[count_providers]); \
+ count_providers++; \
+ } \
+ } while(0)
+
+int
+ProcRRGetProviders (ClientPtr client)
+{
+ REQUEST(xRRGetProvidersReq);
+ xRRGetProvidersReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ int rc;
+ CARD8 *extra;
+ unsigned int extraLen;
+ RRProvider *providers;
+ int total_providers = 0, count_providers = 0;
+
+ REQUEST_SIZE_MATCH(xRRGetProvidersReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv->provider)
+ total_providers++;
+
+ 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.nProviders = total_providers;
+ rep.length = total_providers;
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = malloc(extraLen);
+ if (!extra)
+ return BadAlloc;
+ } else
+ extra = NULL;
+
+ providers = (RRProvider *)extra;
+ ADD_PROVIDER(pScreen);
+ }
+
+ 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;
+ RRCrtc *crtcs;
+ RROutput *outputs;
+ int i;
+ char *name;
+ ScreenPtr provscreen;
+ RRProvider *providers;
+ uint32_t *prov_cap;
+
+ 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.capabilities = provider->capabilities;
+ rep.nameLength = provider->nameLength;
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.nCrtcs = pScrPriv->numCrtcs;
+ rep.nOutputs = pScrPriv->numOutputs;
+
+ /* count associated providers */
+ rep.nAssociatedProviders = 0;
+ rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs +
+ (rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength));
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = malloc(extraLen);
+ if (!extra)
+ return BadAlloc;
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *)extra;
+ outputs = (RROutput *)(crtcs + rep.nCrtcs);
+ providers = (RRProvider *)(outputs + rep.nOutputs);
+ prov_cap = (unsigned int *)(providers + rep.nAssociatedProviders);
+ name = (char *)(prov_cap + rep.nAssociatedProviders);
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ crtcs[i] = pScrPriv->crtcs[i]->id;
+ if (client->swapped)
+ swapl(&crtcs[i]);
+ }
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ outputs[i] = pScrPriv->outputs[i]->id;
+ if (client->swapped)
+ swapl(&outputs[i]);
+ }
+
+ memcpy(name, provider->name, rep.nameLength);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.capabilities);
+ swaps(&rep.nCrtcs);
+ swaps(&rep.nOutputs);
+ swaps(&rep.nameLength);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderInfoReply), (char *)&rep);
+ if (extraLen)
+ {
+ WriteToClient (client, extraLen, (char *) extra);
+ free(extra);
+ }
+ return Success;
+}
+
+RRProviderPtr
+RRProviderCreate(ScreenPtr pScreen, const char *name,
+ int nameLength)
+{
+ RRProviderPtr provider;
+ rrScrPrivPtr pScrPriv;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ provider = calloc(1, sizeof(RRProviderRec) + nameLength + 1);
+ if (!provider)
+ return NULL;
+
+ provider->id = FakeClientID(0);
+ provider->pScreen = pScreen;
+ provider->name = (char *) (provider + 1);
+ provider->nameLength = nameLength;
+ memcpy(provider->name, name, nameLength);
+ provider->name[nameLength] = '\0';
+
+ if (!AddResource (provider->id, RRProviderType, (pointer) provider))
+ return NULL;
+ pScrPriv->provider = provider;
+ return provider;
+}
+
+/*
+ * Destroy a provider at shutdown
+ */
+void
+RRProviderDestroy (RRProviderPtr provider)
+{
+ FreeResource (provider->id, 0);
+}
+
+void
+RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities)
+{
+ provider->capabilities = capabilities;
+}
+
+static int
+RRProviderDestroyResource (pointer value, XID pid)
+{
+ RRProviderPtr provider = (RRProviderPtr)value;
+ ScreenPtr pScreen = provider->pScreen;
+
+ if (pScreen)
+ {
+ rrScrPriv(pScreen);
+
+ pScrPriv->provider = NULL;
+ }
+ 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)
+{
+ int rc = dixLookupResourceByType((void **)provider_p, id,
+ RRProviderType, NullClient, DixReadAccess);
+ if (rc == Success)
+ return TRUE;
+ return FALSE;
+}