Commit 66d92afe authored by Dave Airlie's avatar Dave Airlie

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's avatarKeith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson's avatarAdam Jackson <ajax@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 44eae69f
......@@ -432,14 +432,17 @@ xf86platformAddDevice(int index)
xf86DeleteScreen(xf86GPUScreens[i]);
return -1;
}
scr_index = AddGPUScreen(xf86GPUScreens[i]->ScreenInit, 0, NULL);
dixSetPrivate(&xf86GPUScreens[i]->pScreen->devPrivates,
xf86ScreenKey, xf86GPUScreens[i]);
CreateScratchPixmapsForScreen(xf86GPUScreens[i]->pScreen);
/* attach unbound to 0 protocol screen */
AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
return 0;
}
......
......@@ -18,6 +18,8 @@ librandr_la_SOURCES = \
rroutput.c \
rrpointer.c \
rrproperty.c \
rrprovider.c \
rrproviderproperty.c \
rrscreen.c \
rrsdispatch.c \
rrtransform.h \
......
......@@ -94,6 +94,9 @@ RRCloseScreen(ScreenPtr pScreen)
for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
RROutputDestroy(pScrPriv->outputs[j]);
if (pScrPriv->provider)
RRProviderDestroy(pScrPriv->provider);
free(pScrPriv->crtcs);
free(pScrPriv->outputs);
free(pScrPriv);
......@@ -175,6 +178,47 @@ SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent * from,
/* pad4 */
}
static void
SRRProviderChangeNotifyEvent(xRRProviderChangeNotifyEvent * from,
xRRProviderChangeNotifyEvent * to)
{
to->type = from->type;
to->subCode = from->subCode;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->timestamp, to->timestamp);
cpswapl(from->window, to->window);
cpswapl(from->provider, to->provider);
}
static void
SRRProviderPropertyNotifyEvent(xRRProviderPropertyNotifyEvent * from,
xRRProviderPropertyNotifyEvent * to)
{
to->type = from->type;
to->subCode = from->subCode;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->window, to->window);
cpswapl(from->provider, to->provider);
cpswapl(from->atom, to->atom);
cpswapl(from->timestamp, to->timestamp);
to->state = from->state;
/* pad1 */
/* pad2 */
/* pad3 */
/* pad4 */
}
static void
SRRResourceChangeNotifyEvent(xRRResourceChangeNotifyEvent * from,
xRRResourceChangeNotifyEvent * to)
{
to->type = from->type;
to->subCode = from->subCode;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->timestamp, to->timestamp);
cpswapl(from->window, to->window);
}
static void
SRRNotifyEvent(xEvent *from, xEvent *to)
{
......@@ -191,6 +235,17 @@ SRRNotifyEvent(xEvent *from, xEvent *to)
SRROutputPropertyNotifyEvent((xRROutputPropertyNotifyEvent *) from,
(xRROutputPropertyNotifyEvent *) to);
break;
case RRNotify_ProviderChange:
SRRProviderChangeNotifyEvent((xRRProviderChangeNotifyEvent *) from,
(xRRProviderChangeNotifyEvent *) to);
break;
case RRNotify_ProviderProperty:
SRRProviderPropertyNotifyEvent((xRRProviderPropertyNotifyEvent *) from,
(xRRProviderPropertyNotifyEvent *) to);
break;
case RRNotify_ResourceChange:
SRRResourceChangeNotifyEvent((xRRResourceChangeNotifyEvent *) from,
(xRRResourceChangeNotifyEvent *) to);
default:
break;
}
......@@ -356,7 +411,7 @@ RRExtensionInit(void)
RRModeInitErrorValue();
RRCrtcInitErrorValue();
RROutputInitErrorValue();
RRProviderInitErrorValue();
#ifdef PANORAMIX
RRXineramaExtensionInit();
#endif
......
......@@ -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,16 @@ struct _rrOutput {
void *devPrivate;
};
struct _rrProvider {
RRProvider id;
ScreenPtr pScreen;
uint32_t capabilities;
char *name;
int nameLength;
RRPropertyPtr properties;
Bool pendingProperties;
};
#if RANDR_12_INTERFACE
typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
CARD16 width,
......@@ -197,6 +209,13 @@ typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn,
#endif /* RANDR_13_INTERFACE */
typedef Bool (*RRProviderGetPropertyProcPtr) (ScreenPtr pScreen,
RRProviderPtr provider, Atom property);
typedef Bool (*RRProviderSetPropertyProcPtr) (ScreenPtr pScreen,
RRProviderPtr provider,
Atom property,
RRPropertyValuePtr value);
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations);
typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen);
......@@ -247,6 +266,8 @@ typedef struct _rrScrPriv {
RRSetPanningProcPtr rrSetPanning;
#endif
RRProviderGetPropertyProcPtr rrProviderGetProperty;
RRProviderSetPropertyProcPtr rrProviderSetProperty;
/*
* Private part of the structure; not considered part of the ABI
*/
......@@ -288,6 +309,8 @@ typedef struct _rrScrPriv {
int size;
#endif
Bool discontiguous;
RRProviderPtr provider;
} rrScrPrivRec, *rrScrPrivPtr;
extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
......@@ -331,7 +354,7 @@ extern _X_EXPORT RESTYPE RRClientType, RREventType; /* resource types for ev
extern _X_EXPORT DevPrivateKeyRec RRClientPrivateKeyRec;
#define RRClientPrivateKey (&RRClientPrivateKeyRec)
extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType;
extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType;
#define VERIFY_RR_OUTPUT(id, ptr, a)\
{\
......@@ -363,6 +386,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)
......@@ -824,6 +857,69 @@ extern _X_EXPORT int
extern _X_EXPORT int
ProcRRDeleteOutputProperty(ClientPtr client);
/* rrprovider.c */
extern _X_EXPORT void
RRProviderInitErrorValue(void);
extern _X_EXPORT int
ProcRRGetProviders(ClientPtr client);
extern _X_EXPORT int
ProcRRGetProviderInfo(ClientPtr client);
extern _X_EXPORT Bool
RRProviderInit(void);
extern _X_EXPORT RRProviderPtr
RRProviderCreate(ScreenPtr pScreen, const char *name,
int nameLength);
extern _X_EXPORT void
RRProviderDestroy (RRProviderPtr provider);
extern _X_EXPORT void
RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities);
extern _X_EXPORT Bool
RRProviderLookup(XID id, RRProviderPtr *provider_p);
/* rrproviderproperty.c */
extern _X_EXPORT void
RRDeleteAllProviderProperties(RRProviderPtr provider);
extern _X_EXPORT RRPropertyValuePtr
RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending);
extern _X_EXPORT RRPropertyPtr
RRQueryProviderProperty(RRProviderPtr provider, Atom property);
extern _X_EXPORT void
RRDeleteProviderProperty(RRProviderPtr provider, Atom property);
extern _X_EXPORT int
RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
int format, int mode, unsigned long len,
pointer value, Bool sendevent, Bool pending);
extern _X_EXPORT int
ProcRRGetProviderProperty(ClientPtr client);
extern _X_EXPORT int
ProcRRListProviderProperties(ClientPtr client);
extern _X_EXPORT int
ProcRRQueryProviderProperty(ClientPtr client);
extern _X_EXPORT int
ProcRRConfigureProviderProperty(ClientPtr client);
extern _X_EXPORT int
ProcRRChangeProviderProperty(ClientPtr client);
extern _X_EXPORT int
ProcRRDeleteProviderProperty(ClientPtr client);
/* rrxinerama.c */
#ifdef XINERAMA
extern _X_EXPORT void
......
......@@ -90,7 +90,8 @@ ProcRRSelectInput(ClientPtr client)
if (stuff->enable & (RRScreenChangeNotifyMask |
RRCrtcChangeNotifyMask |
RROutputChangeNotifyMask |
RROutputPropertyNotifyMask)) {
RROutputPropertyNotifyMask |
RRProviderPropertyNotifyMask)) {
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen);
......@@ -241,4 +242,15 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
ProcRRSetPanning, /* 29 */
ProcRRSetOutputPrimary, /* 30 */
ProcRRGetOutputPrimary, /* 31 */
/* V1.4 additions */
ProcRRGetProviders, /* 32 */
ProcRRGetProviderInfo, /* 33 */
NULL, /* 34 */
NULL, /* 35 */
ProcRRListProviderProperties, /* 36 */
ProcRRQueryProviderProperty, /* 37 */
ProcRRConfigureProviderProperty, /* 38 */
ProcRRChangeProviderProperty, /* 39 */
ProcRRDeleteProviderProperty, /* 40 */
ProcRRGetProviderProperty, /* 41 */
};
/*
* 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;
}
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment