Add support for user-defined modelines in RandR.
The RandR protocol spec has several requests in support of user-defined
modes, but the implementation was stubbed out inside the X server. Fill out
the DIX portion and start on the xf86 DDX portion. It might be necessary to
add more code to the DDX to insert the user-defined modes into the output
mode list.
(cherry picked from commit 63cc2a51ef
)
Conflicts:
randr/randrstr.h
Updated code to work in master with recent security API changes.
This commit is contained in:
parent
3bffb28126
commit
2c93083edd
|
@ -728,6 +728,54 @@ xf86RandR12OutputSetProperty (ScreenPtr pScreen,
|
|||
return output->funcs->set_property(output, property, value);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86RandR12OutputValidateMode (ScreenPtr pScreen,
|
||||
RROutputPtr randr_output,
|
||||
RRModePtr randr_mode)
|
||||
{
|
||||
xf86OutputPtr output = randr_output->devPrivate;
|
||||
DisplayModePtr mode = randr_mode->devPrivate;
|
||||
|
||||
if (!mode)
|
||||
{
|
||||
mode = xalloc (sizeof (DisplayModeRec) + randr_mode->mode.nameLength + 1);
|
||||
if (!mode)
|
||||
return FALSE;
|
||||
mode->name = (char *) mode + 1;
|
||||
memcpy (mode->name, randr_mode->name, randr_mode->mode.nameLength);
|
||||
mode->name[randr_mode->mode.nameLength] = '\0';
|
||||
mode->Clock = randr_mode->mode.dotClock / 1000;
|
||||
mode->HDisplay = randr_mode->mode.width;
|
||||
mode->HSyncStart = randr_mode->mode.hSyncStart;
|
||||
mode->HSyncEnd = randr_mode->mode.hSyncEnd;
|
||||
mode->HTotal = randr_mode->mode.hTotal;
|
||||
mode->HSkew = randr_mode->mode.hSkew;
|
||||
|
||||
mode->VDisplay = randr_mode->mode.height;
|
||||
mode->VSyncStart = randr_mode->mode.vSyncStart;
|
||||
mode->VSyncEnd = randr_mode->mode.vSyncEnd;
|
||||
mode->VTotal = randr_mode->mode.vTotal;
|
||||
|
||||
mode->Flags = randr_mode->mode.modeFlags;
|
||||
randr_mode->devPrivate = mode;
|
||||
}
|
||||
if (!output->funcs->mode_valid (output, mode))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
|
||||
{
|
||||
DisplayModePtr mode = randr_mode->devPrivate;
|
||||
|
||||
if (mode)
|
||||
{
|
||||
xfree (mode);
|
||||
randr_mode->devPrivate = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of xf86 modes and a RandR Output object, construct
|
||||
* RandR modes and assign them to the output
|
||||
|
@ -958,6 +1006,8 @@ xf86RandR12Init12 (ScreenPtr pScreen)
|
|||
rp->rrCrtcSet = xf86RandR12CrtcSet;
|
||||
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
|
||||
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
|
||||
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
|
||||
rp->rrModeDestroy = xf86RandR12ModeDestroy;
|
||||
rp->rrSetConfig = NULL;
|
||||
pScrn->PointerMoved = xf86RandR12PointerMoved;
|
||||
if (!xf86RandR12CreateObjects12 (pScreen))
|
||||
|
|
|
@ -73,6 +73,20 @@ miRROutputSetProperty (ScreenPtr pScreen,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
miRROutputValidateMode (ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
RRModePtr mode)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
miRRModeDestroy (ScreenPtr pScreen,
|
||||
RRModePtr mode)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This function assumes that only a single depth can be
|
||||
* displayed at a time, but that all visuals of that depth
|
||||
|
@ -102,7 +116,8 @@ miRandRInit (ScreenPtr pScreen)
|
|||
pScrPriv->rrCrtcSet = miRRCrtcSet;
|
||||
pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
|
||||
pScrPriv->rrOutputSetProperty = miRROutputSetProperty;
|
||||
|
||||
pScrPriv->rrOutputValidateMode = miRROutputValidateMode;
|
||||
pScrPriv->rrModeDestroy = miRRModeDestroy;
|
||||
|
||||
RRScreenSetSizeRange (pScreen,
|
||||
pScreen->width, pScreen->height,
|
||||
|
|
|
@ -80,7 +80,7 @@ struct _rrMode {
|
|||
xRRModeInfo mode;
|
||||
char *name;
|
||||
void *devPrivate;
|
||||
Bool userDefined;
|
||||
ScreenPtr userScreen;
|
||||
};
|
||||
|
||||
struct _rrPropertyValue {
|
||||
|
@ -135,6 +135,8 @@ struct _rrOutput {
|
|||
int numModes;
|
||||
int numPreferred;
|
||||
RRModePtr *modes;
|
||||
int numUserModes;
|
||||
RRModePtr *userModes;
|
||||
Bool changed;
|
||||
RRPropertyPtr properties;
|
||||
void *devPrivate;
|
||||
|
@ -164,6 +166,13 @@ typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
|
|||
Atom property,
|
||||
RRPropertyValuePtr value);
|
||||
|
||||
typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
RRModePtr mode);
|
||||
|
||||
typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen,
|
||||
RRModePtr mode);
|
||||
|
||||
#endif
|
||||
|
||||
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
|
||||
|
@ -208,6 +217,8 @@ typedef struct _rrScrPriv {
|
|||
RRCrtcSetProcPtr rrCrtcSet;
|
||||
RRCrtcSetGammaProcPtr rrCrtcSetGamma;
|
||||
RROutputSetPropertyProcPtr rrOutputSetProperty;
|
||||
RROutputValidateModeProcPtr rrOutputValidateMode;
|
||||
RRModeDestroyProcPtr rrModeDestroy;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -394,6 +405,15 @@ miRROutputSetProperty (ScreenPtr pScreen,
|
|||
Atom property,
|
||||
RRPropertyValuePtr value);
|
||||
|
||||
Bool
|
||||
miRROutputValidateMode (ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
RRModePtr mode);
|
||||
|
||||
void
|
||||
miRRModeDestroy (ScreenPtr pScreen,
|
||||
RRModePtr mode);
|
||||
|
||||
/* randr.c */
|
||||
/*
|
||||
* Send all pending events
|
||||
|
@ -549,6 +569,11 @@ Bool
|
|||
RRCrtcSetRotations (RRCrtcPtr crtc,
|
||||
Rotation rotations);
|
||||
|
||||
/*
|
||||
* Return the area of the frame buffer scanned out by the crtc,
|
||||
* taking into account the current mode and rotation
|
||||
*/
|
||||
|
||||
void
|
||||
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
|
||||
|
||||
|
@ -672,6 +697,14 @@ RROutputSetModes (RROutputPtr output,
|
|||
int numModes,
|
||||
int numPreferred);
|
||||
|
||||
int
|
||||
RROutputAddUserMode (RROutputPtr output,
|
||||
RRModePtr mode);
|
||||
|
||||
int
|
||||
RROutputDeleteUserMode (RROutputPtr output,
|
||||
RRModePtr mode);
|
||||
|
||||
Bool
|
||||
RROutputSetCrtcs (RROutputPtr output,
|
||||
RRCrtcPtr *crtcs,
|
||||
|
|
|
@ -666,10 +666,15 @@ ProcRRSetCrtcConfig (ClientPtr client)
|
|||
return BadMatch;
|
||||
}
|
||||
/* validate mode for this output */
|
||||
for (j = 0; j < outputs[i]->numModes; j++)
|
||||
if (outputs[i]->modes[j] == mode)
|
||||
for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
|
||||
{
|
||||
RRModePtr m = (j < outputs[i]->numModes ?
|
||||
outputs[i]->modes[j] :
|
||||
outputs[i]->userModes[j - outputs[i]->numModes]);
|
||||
if (m == mode)
|
||||
break;
|
||||
if (j == outputs[i]->numModes)
|
||||
}
|
||||
if (j == outputs[i]->numModes + outputs[i]->numUserModes)
|
||||
{
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
|
|
|
@ -157,9 +157,11 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
|
|||
pScrPriv->nSizes = 0;
|
||||
|
||||
/* find size bounds */
|
||||
for (i = 0; i < output->numModes; i++)
|
||||
for (i = 0; i < output->numModes + output->numUserModes; i++)
|
||||
{
|
||||
RRModePtr mode = output->modes[i];
|
||||
RRModePtr mode = (i < output->numModes ?
|
||||
output->modes[i] :
|
||||
output->userModes[i-output->numModes]);
|
||||
CARD16 width = mode->mode.width;
|
||||
CARD16 height = mode->mode.height;
|
||||
|
||||
|
|
217
randr/rrmode.c
217
randr/rrmode.c
|
@ -48,25 +48,13 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *b)
|
|||
static int num_modes;
|
||||
static RRModePtr *modes;
|
||||
|
||||
RRModePtr
|
||||
RRModeGet (xRRModeInfo *modeInfo,
|
||||
const char *name)
|
||||
static RRModePtr
|
||||
RRModeCreate (xRRModeInfo *modeInfo,
|
||||
const char *name,
|
||||
ScreenPtr userScreen)
|
||||
{
|
||||
int i;
|
||||
RRModePtr mode;
|
||||
RRModePtr *newModes;
|
||||
|
||||
for (i = 0; i < num_modes; i++)
|
||||
{
|
||||
mode = modes[i];
|
||||
if (RRModeEqual (&mode->mode, modeInfo) &&
|
||||
!memcmp (name, mode->name, modeInfo->nameLength))
|
||||
{
|
||||
++mode->refcnt;
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
RRModePtr mode, *newModes;
|
||||
|
||||
if (!RRInit ())
|
||||
return NULL;
|
||||
|
||||
|
@ -78,7 +66,7 @@ RRModeGet (xRRModeInfo *modeInfo,
|
|||
mode->name = (char *) (mode + 1);
|
||||
memcpy (mode->name, name, modeInfo->nameLength);
|
||||
mode->name[modeInfo->nameLength] = '\0';
|
||||
mode->userDefined = FALSE;
|
||||
mode->userScreen = userScreen;
|
||||
|
||||
if (num_modes)
|
||||
newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr));
|
||||
|
@ -104,11 +92,75 @@ RRModeGet (xRRModeInfo *modeInfo,
|
|||
return mode;
|
||||
}
|
||||
|
||||
static RRModePtr
|
||||
RRModeFindByName (const char *name,
|
||||
CARD16 nameLength)
|
||||
{
|
||||
int i;
|
||||
RRModePtr mode;
|
||||
|
||||
for (i = 0; i < num_modes; i++)
|
||||
{
|
||||
mode = modes[i];
|
||||
if (mode->mode.nameLength == nameLength &&
|
||||
!memcmp (name, mode->name, nameLength))
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RRModePtr
|
||||
RRModeGet (xRRModeInfo *modeInfo,
|
||||
const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_modes; i++)
|
||||
{
|
||||
RRModePtr mode = modes[i];
|
||||
if (RRModeEqual (&mode->mode, modeInfo) &&
|
||||
!memcmp (name, mode->name, modeInfo->nameLength))
|
||||
{
|
||||
++mode->refcnt;
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
return RRModeCreate (modeInfo, name, NULL);
|
||||
}
|
||||
|
||||
static RRModePtr
|
||||
RRModeCreateUser (ScreenPtr pScreen,
|
||||
xRRModeInfo *modeInfo,
|
||||
const char *name,
|
||||
int *error)
|
||||
{
|
||||
RRModePtr mode;
|
||||
|
||||
mode = RRModeFindByName (name, modeInfo->nameLength);
|
||||
if (mode)
|
||||
{
|
||||
*error = BadName;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mode = RRModeCreate (modeInfo, name, pScreen);
|
||||
if (!mode)
|
||||
{
|
||||
*error = BadAlloc;
|
||||
return NULL;
|
||||
}
|
||||
*error = Success;
|
||||
return mode;
|
||||
}
|
||||
|
||||
RRModePtr *
|
||||
RRModesForScreen (ScreenPtr pScreen, int *num_ret)
|
||||
{
|
||||
rrScrPriv(pScreen);
|
||||
int o, c;
|
||||
int o, c, m;
|
||||
RRModePtr *screen_modes;
|
||||
int num_screen_modes = 0;
|
||||
|
||||
|
@ -122,9 +174,11 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
|
|||
RROutputPtr output = pScrPriv->outputs[o];
|
||||
int m, n;
|
||||
|
||||
for (m = 0; m < output->numModes; m++)
|
||||
for (m = 0; m < output->numModes + output->numUserModes; m++)
|
||||
{
|
||||
RRModePtr mode = output->modes[m];
|
||||
RRModePtr mode = (m < output->numModes ?
|
||||
output->modes[m] :
|
||||
output->userModes[m-output->numModes]);
|
||||
for (n = 0; n < num_screen_modes; n++)
|
||||
if (screen_modes[n] == mode)
|
||||
break;
|
||||
|
@ -150,6 +204,23 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
|
|||
if (n == num_screen_modes)
|
||||
screen_modes[num_screen_modes++] = mode;
|
||||
}
|
||||
/*
|
||||
* Add all user modes for this screen
|
||||
*/
|
||||
for (m = 0; m < num_modes; m++)
|
||||
{
|
||||
RRModePtr mode = modes[m];
|
||||
int n;
|
||||
|
||||
if (mode->userScreen != pScreen)
|
||||
continue;
|
||||
for (n = 0; n < num_screen_modes; n++)
|
||||
if (screen_modes[n] == mode)
|
||||
break;
|
||||
if (n == num_screen_modes)
|
||||
screen_modes[num_screen_modes++] = mode;
|
||||
}
|
||||
|
||||
*num_ret = num_screen_modes;
|
||||
return screen_modes;
|
||||
}
|
||||
|
@ -205,38 +276,122 @@ int
|
|||
ProcRRCreateMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRCreateModeReq);
|
||||
xRRCreateModeReply rep;
|
||||
WindowPtr pWin;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
xRRModeInfo *modeInfo;
|
||||
long units_after;
|
||||
char *name;
|
||||
int error, rc;
|
||||
RRModePtr mode;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRCreateModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
REQUEST_AT_LEAST_SIZE (xRRCreateModeReq);
|
||||
rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
||||
modeInfo = &stuff->modeInfo;
|
||||
name = (char *) (stuff + 1);
|
||||
units_after = (stuff->length - (sizeof (xRRCreateModeReq) >> 2));
|
||||
|
||||
/* check to make sure requested name fits within the data provided */
|
||||
if ((int) (modeInfo->nameLength + 3) >> 2 > units_after)
|
||||
return BadLength;
|
||||
|
||||
mode = RRModeCreateUser (pScreen, modeInfo, name, &error);
|
||||
if (!mode)
|
||||
return error;
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.pad0 = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.mode = mode->mode.id;
|
||||
if (client->swapped)
|
||||
{
|
||||
int n;
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swapl(&rep.mode, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep);
|
||||
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRDestroyMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRDestroyModeReq);
|
||||
RRModePtr mode;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRDestroyModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
mode = LookupIDByType (stuff->mode, RRModeType);
|
||||
if (!mode)
|
||||
{
|
||||
client->errorValue = stuff->mode;
|
||||
return RRErrorBase + BadRRMode;
|
||||
}
|
||||
if (!mode->userScreen)
|
||||
return BadMatch;
|
||||
if (mode->refcnt > 1)
|
||||
return BadAccess;
|
||||
FreeResource (stuff->mode, 0);
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRAddOutputMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRAddOutputModeReq);
|
||||
RRModePtr mode;
|
||||
RROutputPtr output;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
output = LookupOutput(client, stuff->output, DixReadAccess);
|
||||
|
||||
if (!output)
|
||||
{
|
||||
client->errorValue = stuff->output;
|
||||
return RRErrorBase + BadRROutput;
|
||||
}
|
||||
|
||||
mode = LookupIDByType (stuff->mode, RRModeType);
|
||||
if (!mode)
|
||||
{
|
||||
client->errorValue = stuff->mode;
|
||||
return RRErrorBase + BadRRMode;
|
||||
}
|
||||
|
||||
return RROutputAddUserMode (output, mode);
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRDeleteOutputMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRDeleteOutputModeReq);
|
||||
RRModePtr mode;
|
||||
RROutputPtr output;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
output = LookupOutput(client, stuff->output, DixReadAccess);
|
||||
|
||||
if (!output)
|
||||
{
|
||||
client->errorValue = stuff->output;
|
||||
return RRErrorBase + BadRROutput;
|
||||
}
|
||||
|
||||
mode = LookupIDByType (stuff->mode, RRModeType);
|
||||
if (!mode)
|
||||
{
|
||||
client->errorValue = stuff->mode;
|
||||
return RRErrorBase + BadRRMode;
|
||||
}
|
||||
|
||||
return RROutputDeleteUserMode (output, mode);
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ RROutputCreate (const char *name,
|
|||
output->numModes = 0;
|
||||
output->numPreferred = 0;
|
||||
output->modes = NULL;
|
||||
output->numUserModes = 0;
|
||||
output->userModes = NULL;
|
||||
output->properties = NULL;
|
||||
output->changed = FALSE;
|
||||
output->devPrivate = devPrivate;
|
||||
|
@ -192,6 +194,74 @@ RROutputSetModes (RROutputPtr output,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
RROutputAddUserMode (RROutputPtr output,
|
||||
RRModePtr mode)
|
||||
{
|
||||
int m;
|
||||
ScreenPtr pScreen = output->pScreen;
|
||||
rrScrPriv(pScreen);
|
||||
RRModePtr *newModes;
|
||||
|
||||
/* Check to see if this mode is already listed for this output */
|
||||
for (m = 0; m < output->numModes + output->numUserModes; m++)
|
||||
{
|
||||
RRModePtr e = (m < output->numModes ?
|
||||
output->modes[m] :
|
||||
output->userModes[m - output->numModes]);
|
||||
if (mode == e)
|
||||
return Success;
|
||||
}
|
||||
|
||||
/* Check with the DDX to see if this mode is OK */
|
||||
if (pScrPriv->rrOutputValidateMode)
|
||||
if (!pScrPriv->rrOutputValidateMode (pScreen, output, mode))
|
||||
return BadMatch;
|
||||
|
||||
if (output->userModes)
|
||||
newModes = xrealloc (output->userModes,
|
||||
(output->numUserModes + 1) * sizeof (RRModePtr));
|
||||
else
|
||||
newModes = xalloc (sizeof (RRModePtr));
|
||||
if (!newModes)
|
||||
return BadAlloc;
|
||||
|
||||
output->userModes = newModes;
|
||||
output->userModes[output->numUserModes++] = mode;
|
||||
++mode->refcnt;
|
||||
RROutputChanged (output, TRUE);
|
||||
RRTellChanged (pScreen);
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
RROutputDeleteUserMode (RROutputPtr output,
|
||||
RRModePtr mode)
|
||||
{
|
||||
int m;
|
||||
|
||||
/* Find this mode in the user mode list */
|
||||
for (m = 0; m < output->numUserModes; m++)
|
||||
{
|
||||
RRModePtr e = output->userModes[m];
|
||||
|
||||
if (mode == e)
|
||||
break;
|
||||
}
|
||||
/* Not there, access error */
|
||||
if (m == output->numUserModes)
|
||||
return BadAccess;
|
||||
|
||||
/* make sure the mode isn't active for this output */
|
||||
if (output->crtc && output->crtc->mode == mode)
|
||||
return BadMatch;
|
||||
|
||||
memmove (output->userModes + m, output->userModes + m + 1,
|
||||
(output->numUserModes - m - 1) * sizeof (RRModePtr));
|
||||
RRModeDestroy (mode);
|
||||
return Success;
|
||||
}
|
||||
|
||||
Bool
|
||||
RROutputSetCrtcs (RROutputPtr output,
|
||||
RRCrtcPtr *crtcs,
|
||||
|
@ -308,9 +378,9 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
|
|||
* Destroy a Output at shutdown
|
||||
*/
|
||||
void
|
||||
RROutputDestroy (RROutputPtr crtc)
|
||||
RROutputDestroy (RROutputPtr output)
|
||||
{
|
||||
FreeResource (crtc->id, 0);
|
||||
FreeResource (output->id, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -318,6 +388,7 @@ RROutputDestroyResource (pointer value, XID pid)
|
|||
{
|
||||
RROutputPtr output = (RROutputPtr) value;
|
||||
ScreenPtr pScreen = output->pScreen;
|
||||
int m;
|
||||
|
||||
if (pScreen)
|
||||
{
|
||||
|
@ -335,8 +406,15 @@ RROutputDestroyResource (pointer value, XID pid)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* XXX destroy all modes? */
|
||||
if (output->modes)
|
||||
xfree (output->modes);
|
||||
|
||||
for (m = 0; m < output->numUserModes; m++)
|
||||
RRModeDestroy (output->userModes[m]);
|
||||
if (output->userModes)
|
||||
xfree (output->userModes);
|
||||
|
||||
if (output->crtcs)
|
||||
xfree (output->crtcs);
|
||||
if (output->clones)
|
||||
|
@ -383,7 +461,10 @@ ProcRRGetOutputInfo (ClientPtr client)
|
|||
output = LookupOutput(client, stuff->output, DixReadAccess);
|
||||
|
||||
if (!output)
|
||||
{
|
||||
client->errorValue = stuff->output;
|
||||
return RRErrorBase + BadRROutput;
|
||||
}
|
||||
|
||||
pScreen = output->pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
@ -398,13 +479,13 @@ ProcRRGetOutputInfo (ClientPtr client)
|
|||
rep.connection = output->connection;
|
||||
rep.subpixelOrder = output->subpixelOrder;
|
||||
rep.nCrtcs = output->numCrtcs;
|
||||
rep.nModes = output->numModes;
|
||||
rep.nModes = output->numModes + output->numUserModes;
|
||||
rep.nPreferred = output->numPreferred;
|
||||
rep.nClones = output->numClones;
|
||||
rep.nameLength = output->nameLength;
|
||||
|
||||
extraLen = ((output->numCrtcs +
|
||||
output->numModes +
|
||||
output->numModes + output->numUserModes +
|
||||
output->numClones +
|
||||
((rep.nameLength + 3) >> 2)) << 2);
|
||||
|
||||
|
@ -420,7 +501,7 @@ ProcRRGetOutputInfo (ClientPtr client)
|
|||
|
||||
crtcs = (RRCrtc *) extra;
|
||||
modes = (RRMode *) (crtcs + output->numCrtcs);
|
||||
clones = (RROutput *) (modes + output->numModes);
|
||||
clones = (RROutput *) (modes + output->numModes + output->numUserModes);
|
||||
name = (char *) (clones + output->numClones);
|
||||
|
||||
for (i = 0; i < output->numCrtcs; i++)
|
||||
|
@ -429,9 +510,12 @@ ProcRRGetOutputInfo (ClientPtr client)
|
|||
if (client->swapped)
|
||||
swapl (&crtcs[i], n);
|
||||
}
|
||||
for (i = 0; i < output->numModes; i++)
|
||||
for (i = 0; i < output->numModes + output->numUserModes; i++)
|
||||
{
|
||||
modes[i] = output->modes[i]->mode.id;
|
||||
if (i < output->numModes)
|
||||
modes[i] = output->modes[i]->mode.id;
|
||||
else
|
||||
modes[i] = output->userModes[i - output->numModes]->mode.id;
|
||||
if (client->swapped)
|
||||
swapl (&modes[i], n);
|
||||
}
|
||||
|
|
|
@ -473,7 +473,7 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
|||
{
|
||||
RR10DataPtr data;
|
||||
RRScreenSizePtr size;
|
||||
int nmode = output->numModes;
|
||||
int nmode = output->numModes + output->numUserModes;
|
||||
int o, os, l, r;
|
||||
RRScreenRatePtr refresh;
|
||||
CARD16 vRefresh;
|
||||
|
@ -500,11 +500,14 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
|||
/*
|
||||
* find modes not yet listed
|
||||
*/
|
||||
for (o = 0; o < output->numModes; o++)
|
||||
for (o = 0; o < output->numModes + output->numUserModes; o++)
|
||||
{
|
||||
if (used[o]) continue;
|
||||
|
||||
mode = output->modes[o];
|
||||
if (o < output->numModes)
|
||||
mode = output->modes[o];
|
||||
else
|
||||
mode = output->userModes[o - output->numModes];
|
||||
|
||||
l = data->nsize;
|
||||
size[l].id = data->nsize;
|
||||
|
@ -524,9 +527,12 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
|||
/*
|
||||
* Find all modes with matching size
|
||||
*/
|
||||
for (os = o; os < output->numModes; os++)
|
||||
for (os = o; os < output->numModes + output->numUserModes; os++)
|
||||
{
|
||||
mode = output->modes[os];
|
||||
if (os < output->numModes)
|
||||
mode = output->modes[os];
|
||||
else
|
||||
mode = output->userModes[os - output->numModes];
|
||||
if (mode->mode.width == size[l].width &&
|
||||
mode->mode.height == size[l].height)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user