diff options
author | Dave Airlie <airlied@redhat.com> | 2012-05-04 10:35:13 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-04 10:35:13 +0100 |
commit | f55cc4048b96bee102eb184023520648ac3690fc (patch) | |
tree | eeeea0c27d20438e9d27abfedb05e0dd1027aeab | |
parent | 69fc7f94fdc9348597841c280e06e4bd711b2a06 (diff) |
randr: port over provider code from v2
-rw-r--r-- | randr/Makefile.am | 1 | ||||
-rw-r--r-- | randr/randr.c | 5 | ||||
-rw-r--r-- | randr/randrstr.h | 50 | ||||
-rw-r--r-- | randr/rrdispatch.c | 8 | ||||
-rw-r--r-- | randr/rrprovider.c | 260 |
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; +} |