randr: hook up output slave to screen resources return
When the client asks for the screen resources list, it will now get a list of crtc/outputs for the master + all attached slaves, this will let randr configure all attached slave devices properly. Keith asked I merge the two functions, but not just yet, the current multi screen code doesn't handle primary yet properly, will fix it up later. Reviewed-by: Keith Packard <keithp@keithp.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
88bc02bfaa
commit
bec4cb72c5
169
randr/rrscreen.c
169
randr/rrscreen.c
|
@ -292,6 +292,172 @@ ProcRRSetScreenSize(ClientPtr client)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define update_totals(gpuscreen, pScrPriv) do { \
|
||||||
|
total_crtcs += pScrPriv->numCrtcs; \
|
||||||
|
total_outputs += pScrPriv->numOutputs; \
|
||||||
|
modes = RRModesForScreen(gpuscreen, &num_modes); \
|
||||||
|
if (!modes) \
|
||||||
|
return BadAlloc; \
|
||||||
|
for (j = 0; j < num_modes; j++) \
|
||||||
|
total_name_len += modes[j]->mode.nameLength; \
|
||||||
|
total_modes += num_modes; \
|
||||||
|
free(modes); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
static inline void swap_modeinfos(xRRModeInfo *modeinfos, int i)
|
||||||
|
{
|
||||||
|
swapl(&modeinfos[i].id);
|
||||||
|
swaps(&modeinfos[i].width);
|
||||||
|
swaps(&modeinfos[i].height);
|
||||||
|
swapl(&modeinfos[i].dotClock);
|
||||||
|
swaps(&modeinfos[i].hSyncStart);
|
||||||
|
swaps(&modeinfos[i].hSyncEnd);
|
||||||
|
swaps(&modeinfos[i].hTotal);
|
||||||
|
swaps(&modeinfos[i].hSkew);
|
||||||
|
swaps(&modeinfos[i].vSyncStart);
|
||||||
|
swaps(&modeinfos[i].vSyncEnd);
|
||||||
|
swaps(&modeinfos[i].vTotal);
|
||||||
|
swaps(&modeinfos[i].nameLength);
|
||||||
|
swapl(&modeinfos[i].modeFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define update_arrays(gpuscreen, pScrPriv) do { \
|
||||||
|
for (j = 0; j < pScrPriv->numCrtcs; j++) { \
|
||||||
|
crtcs[crtc_count] = pScrPriv->crtcs[j]->id; \
|
||||||
|
if (client->swapped) \
|
||||||
|
swapl(&crtcs[crtc_count]); \
|
||||||
|
crtc_count++; \
|
||||||
|
} \
|
||||||
|
for (j = 0; j < pScrPriv->numOutputs; j++) { \
|
||||||
|
outputs[output_count] = pScrPriv->outputs[j]->id; \
|
||||||
|
if (client->swapped) \
|
||||||
|
swapl(&outputs[output_count]); \
|
||||||
|
output_count++; \
|
||||||
|
} \
|
||||||
|
{ \
|
||||||
|
RRModePtr mode; \
|
||||||
|
modes = RRModesForScreen(gpuscreen, &num_modes); \
|
||||||
|
for (j = 0; j < num_modes; j++) { \
|
||||||
|
mode = modes[j]; \
|
||||||
|
modeinfos[mode_count] = mode->mode; \
|
||||||
|
if (client->swapped) { \
|
||||||
|
swap_modeinfos(modeinfos, mode_count); \
|
||||||
|
} \
|
||||||
|
memcpy(names, mode->name, mode->mode.nameLength); \
|
||||||
|
names += mode->mode.nameLength; \
|
||||||
|
mode_count++; \
|
||||||
|
} \
|
||||||
|
free(modes); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static int
|
||||||
|
rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
int total_crtcs, total_outputs, total_modes, total_name_len;
|
||||||
|
int crtc_count, output_count, mode_count;
|
||||||
|
ScreenPtr iter;
|
||||||
|
rrScrPrivPtr pScrPriv;
|
||||||
|
int num_modes;
|
||||||
|
RRModePtr *modes;
|
||||||
|
xRRGetScreenResourcesReply rep;
|
||||||
|
unsigned long extraLen;
|
||||||
|
CARD8 *extra;
|
||||||
|
RRCrtc *crtcs;
|
||||||
|
RROutput *outputs;
|
||||||
|
xRRModeInfo *modeinfos;
|
||||||
|
CARD8 *names;
|
||||||
|
|
||||||
|
/* we need to iterate all the GPU masters and all their output slaves */
|
||||||
|
total_crtcs = 0;
|
||||||
|
total_outputs = 0;
|
||||||
|
total_modes = 0;
|
||||||
|
total_name_len = 0;
|
||||||
|
|
||||||
|
pScrPriv = rrGetScrPriv(pScreen);
|
||||||
|
|
||||||
|
if (query && pScrPriv)
|
||||||
|
if (!RRGetInfo(pScreen, query))
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
|
update_totals(pScreen, pScrPriv);
|
||||||
|
|
||||||
|
xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
|
||||||
|
pScrPriv = rrGetScrPriv(iter);
|
||||||
|
|
||||||
|
if (query)
|
||||||
|
if (!RRGetInfo(iter, query))
|
||||||
|
return BadAlloc;
|
||||||
|
update_totals(iter, pScrPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorF("reporting %d %d %d %d\n", total_crtcs, total_outputs, total_modes, total_name_len);
|
||||||
|
|
||||||
|
pScrPriv = rrGetScrPriv(pScreen);
|
||||||
|
rep.pad = 0;
|
||||||
|
rep.type = X_Reply;
|
||||||
|
rep.sequenceNumber = client->sequence;
|
||||||
|
rep.length = 0;
|
||||||
|
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
|
||||||
|
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
|
||||||
|
rep.nCrtcs = total_crtcs;
|
||||||
|
rep.nOutputs = total_outputs;
|
||||||
|
rep.nModes = total_modes;
|
||||||
|
rep.nbytesNames = total_name_len;
|
||||||
|
|
||||||
|
rep.length = (total_crtcs + total_outputs + total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) +
|
||||||
|
bytes_to_int32(rep.nbytesNames));
|
||||||
|
|
||||||
|
extraLen = rep.length << 2;
|
||||||
|
if (extraLen) {
|
||||||
|
extra = malloc(extraLen);
|
||||||
|
if (!extra) {
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
extra = NULL;
|
||||||
|
|
||||||
|
crtcs = (RRCrtc *)extra;
|
||||||
|
outputs = (RROutput *)(crtcs + total_crtcs);
|
||||||
|
modeinfos = (xRRModeInfo *)(outputs + total_outputs);
|
||||||
|
names = (CARD8 *)(modeinfos + total_modes);
|
||||||
|
|
||||||
|
/* TODO primary */
|
||||||
|
crtc_count = 0;
|
||||||
|
output_count = 0;
|
||||||
|
mode_count = 0;
|
||||||
|
|
||||||
|
pScrPriv = rrGetScrPriv(pScreen);
|
||||||
|
update_arrays(pScreen, pScrPriv);
|
||||||
|
|
||||||
|
xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
|
||||||
|
pScrPriv = rrGetScrPriv(iter);
|
||||||
|
|
||||||
|
update_arrays(iter, pScrPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
|
||||||
|
if (client->swapped) {
|
||||||
|
swaps(&rep.sequenceNumber);
|
||||||
|
swapl(&rep.length);
|
||||||
|
swapl(&rep.timestamp);
|
||||||
|
swapl(&rep.configTimestamp);
|
||||||
|
swaps(&rep.nCrtcs);
|
||||||
|
swaps(&rep.nOutputs);
|
||||||
|
swaps(&rep.nModes);
|
||||||
|
swaps(&rep.nbytesNames);
|
||||||
|
}
|
||||||
|
WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *) &rep);
|
||||||
|
if (extraLen) {
|
||||||
|
WriteToClient(client, extraLen, (char *) extra);
|
||||||
|
free(extra);
|
||||||
|
}
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rrGetScreenResources(ClientPtr client, Bool query)
|
rrGetScreenResources(ClientPtr client, Bool query)
|
||||||
{
|
{
|
||||||
|
@ -321,6 +487,9 @@ rrGetScreenResources(ClientPtr client, Bool query)
|
||||||
if (!RRGetInfo(pScreen, query))
|
if (!RRGetInfo(pScreen, query))
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
|
if (!xorg_list_is_empty(&pScreen->output_slave_list))
|
||||||
|
return rrGetMultiScreenResources(client, query, pScreen);
|
||||||
|
|
||||||
if (!pScrPriv) {
|
if (!pScrPriv) {
|
||||||
rep.type = X_Reply;
|
rep.type = X_Reply;
|
||||||
rep.sequenceNumber = client->sequence;
|
rep.sequenceNumber = client->sequence;
|
||||||
|
|
Loading…
Reference in New Issue