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 63cc2a51ef87130c632a874672a8c9167f14314e) 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);
|
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
|
* Given a list of xf86 modes and a RandR Output object, construct
|
||||||
* RandR modes and assign them to the output
|
* RandR modes and assign them to the output
|
||||||
|
@ -958,6 +1006,8 @@ xf86RandR12Init12 (ScreenPtr pScreen)
|
||||||
rp->rrCrtcSet = xf86RandR12CrtcSet;
|
rp->rrCrtcSet = xf86RandR12CrtcSet;
|
||||||
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
|
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
|
||||||
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
|
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
|
||||||
|
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
|
||||||
|
rp->rrModeDestroy = xf86RandR12ModeDestroy;
|
||||||
rp->rrSetConfig = NULL;
|
rp->rrSetConfig = NULL;
|
||||||
pScrn->PointerMoved = xf86RandR12PointerMoved;
|
pScrn->PointerMoved = xf86RandR12PointerMoved;
|
||||||
if (!xf86RandR12CreateObjects12 (pScreen))
|
if (!xf86RandR12CreateObjects12 (pScreen))
|
||||||
|
|
|
@ -73,6 +73,20 @@ miRROutputSetProperty (ScreenPtr pScreen,
|
||||||
return TRUE;
|
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
|
* This function assumes that only a single depth can be
|
||||||
* displayed at a time, but that all visuals of that depth
|
* displayed at a time, but that all visuals of that depth
|
||||||
|
@ -102,7 +116,8 @@ miRandRInit (ScreenPtr pScreen)
|
||||||
pScrPriv->rrCrtcSet = miRRCrtcSet;
|
pScrPriv->rrCrtcSet = miRRCrtcSet;
|
||||||
pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
|
pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
|
||||||
pScrPriv->rrOutputSetProperty = miRROutputSetProperty;
|
pScrPriv->rrOutputSetProperty = miRROutputSetProperty;
|
||||||
|
pScrPriv->rrOutputValidateMode = miRROutputValidateMode;
|
||||||
|
pScrPriv->rrModeDestroy = miRRModeDestroy;
|
||||||
|
|
||||||
RRScreenSetSizeRange (pScreen,
|
RRScreenSetSizeRange (pScreen,
|
||||||
pScreen->width, pScreen->height,
|
pScreen->width, pScreen->height,
|
||||||
|
|
|
@ -80,7 +80,7 @@ struct _rrMode {
|
||||||
xRRModeInfo mode;
|
xRRModeInfo mode;
|
||||||
char *name;
|
char *name;
|
||||||
void *devPrivate;
|
void *devPrivate;
|
||||||
Bool userDefined;
|
ScreenPtr userScreen;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _rrPropertyValue {
|
struct _rrPropertyValue {
|
||||||
|
@ -135,6 +135,8 @@ struct _rrOutput {
|
||||||
int numModes;
|
int numModes;
|
||||||
int numPreferred;
|
int numPreferred;
|
||||||
RRModePtr *modes;
|
RRModePtr *modes;
|
||||||
|
int numUserModes;
|
||||||
|
RRModePtr *userModes;
|
||||||
Bool changed;
|
Bool changed;
|
||||||
RRPropertyPtr properties;
|
RRPropertyPtr properties;
|
||||||
void *devPrivate;
|
void *devPrivate;
|
||||||
|
@ -164,6 +166,13 @@ typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
|
||||||
Atom property,
|
Atom property,
|
||||||
RRPropertyValuePtr value);
|
RRPropertyValuePtr value);
|
||||||
|
|
||||||
|
typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen,
|
||||||
|
RROutputPtr output,
|
||||||
|
RRModePtr mode);
|
||||||
|
|
||||||
|
typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen,
|
||||||
|
RRModePtr mode);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
|
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
|
||||||
|
@ -208,6 +217,8 @@ typedef struct _rrScrPriv {
|
||||||
RRCrtcSetProcPtr rrCrtcSet;
|
RRCrtcSetProcPtr rrCrtcSet;
|
||||||
RRCrtcSetGammaProcPtr rrCrtcSetGamma;
|
RRCrtcSetGammaProcPtr rrCrtcSetGamma;
|
||||||
RROutputSetPropertyProcPtr rrOutputSetProperty;
|
RROutputSetPropertyProcPtr rrOutputSetProperty;
|
||||||
|
RROutputValidateModeProcPtr rrOutputValidateMode;
|
||||||
|
RRModeDestroyProcPtr rrModeDestroy;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -394,6 +405,15 @@ miRROutputSetProperty (ScreenPtr pScreen,
|
||||||
Atom property,
|
Atom property,
|
||||||
RRPropertyValuePtr value);
|
RRPropertyValuePtr value);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
miRROutputValidateMode (ScreenPtr pScreen,
|
||||||
|
RROutputPtr output,
|
||||||
|
RRModePtr mode);
|
||||||
|
|
||||||
|
void
|
||||||
|
miRRModeDestroy (ScreenPtr pScreen,
|
||||||
|
RRModePtr mode);
|
||||||
|
|
||||||
/* randr.c */
|
/* randr.c */
|
||||||
/*
|
/*
|
||||||
* Send all pending events
|
* Send all pending events
|
||||||
|
@ -549,6 +569,11 @@ Bool
|
||||||
RRCrtcSetRotations (RRCrtcPtr crtc,
|
RRCrtcSetRotations (RRCrtcPtr crtc,
|
||||||
Rotation rotations);
|
Rotation rotations);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the area of the frame buffer scanned out by the crtc,
|
||||||
|
* taking into account the current mode and rotation
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
|
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
|
||||||
|
|
||||||
|
@ -672,6 +697,14 @@ RROutputSetModes (RROutputPtr output,
|
||||||
int numModes,
|
int numModes,
|
||||||
int numPreferred);
|
int numPreferred);
|
||||||
|
|
||||||
|
int
|
||||||
|
RROutputAddUserMode (RROutputPtr output,
|
||||||
|
RRModePtr mode);
|
||||||
|
|
||||||
|
int
|
||||||
|
RROutputDeleteUserMode (RROutputPtr output,
|
||||||
|
RRModePtr mode);
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
RROutputSetCrtcs (RROutputPtr output,
|
RROutputSetCrtcs (RROutputPtr output,
|
||||||
RRCrtcPtr *crtcs,
|
RRCrtcPtr *crtcs,
|
||||||
|
|
|
@ -666,10 +666,15 @@ ProcRRSetCrtcConfig (ClientPtr client)
|
||||||
return BadMatch;
|
return BadMatch;
|
||||||
}
|
}
|
||||||
/* validate mode for this output */
|
/* validate mode for this output */
|
||||||
for (j = 0; j < outputs[i]->numModes; j++)
|
for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
|
||||||
if (outputs[i]->modes[j] == mode)
|
{
|
||||||
|
RRModePtr m = (j < outputs[i]->numModes ?
|
||||||
|
outputs[i]->modes[j] :
|
||||||
|
outputs[i]->userModes[j - outputs[i]->numModes]);
|
||||||
|
if (m == mode)
|
||||||
break;
|
break;
|
||||||
if (j == outputs[i]->numModes)
|
}
|
||||||
|
if (j == outputs[i]->numModes + outputs[i]->numUserModes)
|
||||||
{
|
{
|
||||||
if (outputs)
|
if (outputs)
|
||||||
xfree (outputs);
|
xfree (outputs);
|
||||||
|
|
|
@ -157,9 +157,11 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
|
||||||
pScrPriv->nSizes = 0;
|
pScrPriv->nSizes = 0;
|
||||||
|
|
||||||
/* find size bounds */
|
/* 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 width = mode->mode.width;
|
||||||
CARD16 height = mode->mode.height;
|
CARD16 height = mode->mode.height;
|
||||||
|
|
||||||
|
|
215
randr/rrmode.c
215
randr/rrmode.c
|
@ -48,24 +48,12 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *b)
|
||||||
static int num_modes;
|
static int num_modes;
|
||||||
static RRModePtr *modes;
|
static RRModePtr *modes;
|
||||||
|
|
||||||
RRModePtr
|
static RRModePtr
|
||||||
RRModeGet (xRRModeInfo *modeInfo,
|
RRModeCreate (xRRModeInfo *modeInfo,
|
||||||
const char *name)
|
const char *name,
|
||||||
|
ScreenPtr userScreen)
|
||||||
{
|
{
|
||||||
int i;
|
RRModePtr mode, *newModes;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RRInit ())
|
if (!RRInit ())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -78,7 +66,7 @@ RRModeGet (xRRModeInfo *modeInfo,
|
||||||
mode->name = (char *) (mode + 1);
|
mode->name = (char *) (mode + 1);
|
||||||
memcpy (mode->name, name, modeInfo->nameLength);
|
memcpy (mode->name, name, modeInfo->nameLength);
|
||||||
mode->name[modeInfo->nameLength] = '\0';
|
mode->name[modeInfo->nameLength] = '\0';
|
||||||
mode->userDefined = FALSE;
|
mode->userScreen = userScreen;
|
||||||
|
|
||||||
if (num_modes)
|
if (num_modes)
|
||||||
newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr));
|
newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr));
|
||||||
|
@ -104,11 +92,75 @@ RRModeGet (xRRModeInfo *modeInfo,
|
||||||
return mode;
|
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 *
|
RRModePtr *
|
||||||
RRModesForScreen (ScreenPtr pScreen, int *num_ret)
|
RRModesForScreen (ScreenPtr pScreen, int *num_ret)
|
||||||
{
|
{
|
||||||
rrScrPriv(pScreen);
|
rrScrPriv(pScreen);
|
||||||
int o, c;
|
int o, c, m;
|
||||||
RRModePtr *screen_modes;
|
RRModePtr *screen_modes;
|
||||||
int num_screen_modes = 0;
|
int num_screen_modes = 0;
|
||||||
|
|
||||||
|
@ -122,9 +174,11 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
|
||||||
RROutputPtr output = pScrPriv->outputs[o];
|
RROutputPtr output = pScrPriv->outputs[o];
|
||||||
int m, n;
|
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++)
|
for (n = 0; n < num_screen_modes; n++)
|
||||||
if (screen_modes[n] == mode)
|
if (screen_modes[n] == mode)
|
||||||
break;
|
break;
|
||||||
|
@ -150,6 +204,23 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
|
||||||
if (n == num_screen_modes)
|
if (n == num_screen_modes)
|
||||||
screen_modes[num_screen_modes++] = mode;
|
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;
|
*num_ret = num_screen_modes;
|
||||||
return screen_modes;
|
return screen_modes;
|
||||||
}
|
}
|
||||||
|
@ -205,38 +276,122 @@ int
|
||||||
ProcRRCreateMode (ClientPtr client)
|
ProcRRCreateMode (ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xRRCreateModeReq);
|
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);
|
REQUEST_AT_LEAST_SIZE (xRRCreateModeReq);
|
||||||
(void) stuff;
|
rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
|
||||||
return BadImplementation;
|
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
|
int
|
||||||
ProcRRDestroyMode (ClientPtr client)
|
ProcRRDestroyMode (ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xRRDestroyModeReq);
|
REQUEST(xRRDestroyModeReq);
|
||||||
|
RRModePtr mode;
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xRRDestroyModeReq);
|
REQUEST_SIZE_MATCH(xRRDestroyModeReq);
|
||||||
(void) stuff;
|
mode = LookupIDByType (stuff->mode, RRModeType);
|
||||||
return BadImplementation;
|
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
|
int
|
||||||
ProcRRAddOutputMode (ClientPtr client)
|
ProcRRAddOutputMode (ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xRRAddOutputModeReq);
|
REQUEST(xRRAddOutputModeReq);
|
||||||
|
RRModePtr mode;
|
||||||
|
RROutputPtr output;
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
|
REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
|
||||||
(void) stuff;
|
output = LookupOutput(client, stuff->output, DixReadAccess);
|
||||||
return BadImplementation;
|
|
||||||
|
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
|
int
|
||||||
ProcRRDeleteOutputMode (ClientPtr client)
|
ProcRRDeleteOutputMode (ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xRRDeleteOutputModeReq);
|
REQUEST(xRRDeleteOutputModeReq);
|
||||||
|
RRModePtr mode;
|
||||||
|
RROutputPtr output;
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
|
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
|
||||||
(void) stuff;
|
output = LookupOutput(client, stuff->output, DixReadAccess);
|
||||||
return BadImplementation;
|
|
||||||
|
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->numModes = 0;
|
||||||
output->numPreferred = 0;
|
output->numPreferred = 0;
|
||||||
output->modes = NULL;
|
output->modes = NULL;
|
||||||
|
output->numUserModes = 0;
|
||||||
|
output->userModes = NULL;
|
||||||
output->properties = NULL;
|
output->properties = NULL;
|
||||||
output->changed = FALSE;
|
output->changed = FALSE;
|
||||||
output->devPrivate = devPrivate;
|
output->devPrivate = devPrivate;
|
||||||
|
@ -192,6 +194,74 @@ RROutputSetModes (RROutputPtr output,
|
||||||
return TRUE;
|
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
|
Bool
|
||||||
RROutputSetCrtcs (RROutputPtr output,
|
RROutputSetCrtcs (RROutputPtr output,
|
||||||
RRCrtcPtr *crtcs,
|
RRCrtcPtr *crtcs,
|
||||||
|
@ -308,9 +378,9 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
|
||||||
* Destroy a Output at shutdown
|
* Destroy a Output at shutdown
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RROutputDestroy (RROutputPtr crtc)
|
RROutputDestroy (RROutputPtr output)
|
||||||
{
|
{
|
||||||
FreeResource (crtc->id, 0);
|
FreeResource (output->id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -318,6 +388,7 @@ RROutputDestroyResource (pointer value, XID pid)
|
||||||
{
|
{
|
||||||
RROutputPtr output = (RROutputPtr) value;
|
RROutputPtr output = (RROutputPtr) value;
|
||||||
ScreenPtr pScreen = output->pScreen;
|
ScreenPtr pScreen = output->pScreen;
|
||||||
|
int m;
|
||||||
|
|
||||||
if (pScreen)
|
if (pScreen)
|
||||||
{
|
{
|
||||||
|
@ -335,8 +406,15 @@ RROutputDestroyResource (pointer value, XID pid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* XXX destroy all modes? */
|
||||||
if (output->modes)
|
if (output->modes)
|
||||||
xfree (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)
|
if (output->crtcs)
|
||||||
xfree (output->crtcs);
|
xfree (output->crtcs);
|
||||||
if (output->clones)
|
if (output->clones)
|
||||||
|
@ -383,7 +461,10 @@ ProcRRGetOutputInfo (ClientPtr client)
|
||||||
output = LookupOutput(client, stuff->output, DixReadAccess);
|
output = LookupOutput(client, stuff->output, DixReadAccess);
|
||||||
|
|
||||||
if (!output)
|
if (!output)
|
||||||
|
{
|
||||||
|
client->errorValue = stuff->output;
|
||||||
return RRErrorBase + BadRROutput;
|
return RRErrorBase + BadRROutput;
|
||||||
|
}
|
||||||
|
|
||||||
pScreen = output->pScreen;
|
pScreen = output->pScreen;
|
||||||
pScrPriv = rrGetScrPriv(pScreen);
|
pScrPriv = rrGetScrPriv(pScreen);
|
||||||
|
@ -398,13 +479,13 @@ ProcRRGetOutputInfo (ClientPtr client)
|
||||||
rep.connection = output->connection;
|
rep.connection = output->connection;
|
||||||
rep.subpixelOrder = output->subpixelOrder;
|
rep.subpixelOrder = output->subpixelOrder;
|
||||||
rep.nCrtcs = output->numCrtcs;
|
rep.nCrtcs = output->numCrtcs;
|
||||||
rep.nModes = output->numModes;
|
rep.nModes = output->numModes + output->numUserModes;
|
||||||
rep.nPreferred = output->numPreferred;
|
rep.nPreferred = output->numPreferred;
|
||||||
rep.nClones = output->numClones;
|
rep.nClones = output->numClones;
|
||||||
rep.nameLength = output->nameLength;
|
rep.nameLength = output->nameLength;
|
||||||
|
|
||||||
extraLen = ((output->numCrtcs +
|
extraLen = ((output->numCrtcs +
|
||||||
output->numModes +
|
output->numModes + output->numUserModes +
|
||||||
output->numClones +
|
output->numClones +
|
||||||
((rep.nameLength + 3) >> 2)) << 2);
|
((rep.nameLength + 3) >> 2)) << 2);
|
||||||
|
|
||||||
|
@ -420,7 +501,7 @@ ProcRRGetOutputInfo (ClientPtr client)
|
||||||
|
|
||||||
crtcs = (RRCrtc *) extra;
|
crtcs = (RRCrtc *) extra;
|
||||||
modes = (RRMode *) (crtcs + output->numCrtcs);
|
modes = (RRMode *) (crtcs + output->numCrtcs);
|
||||||
clones = (RROutput *) (modes + output->numModes);
|
clones = (RROutput *) (modes + output->numModes + output->numUserModes);
|
||||||
name = (char *) (clones + output->numClones);
|
name = (char *) (clones + output->numClones);
|
||||||
|
|
||||||
for (i = 0; i < output->numCrtcs; i++)
|
for (i = 0; i < output->numCrtcs; i++)
|
||||||
|
@ -429,9 +510,12 @@ ProcRRGetOutputInfo (ClientPtr client)
|
||||||
if (client->swapped)
|
if (client->swapped)
|
||||||
swapl (&crtcs[i], n);
|
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)
|
if (client->swapped)
|
||||||
swapl (&modes[i], n);
|
swapl (&modes[i], n);
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,7 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
||||||
{
|
{
|
||||||
RR10DataPtr data;
|
RR10DataPtr data;
|
||||||
RRScreenSizePtr size;
|
RRScreenSizePtr size;
|
||||||
int nmode = output->numModes;
|
int nmode = output->numModes + output->numUserModes;
|
||||||
int o, os, l, r;
|
int o, os, l, r;
|
||||||
RRScreenRatePtr refresh;
|
RRScreenRatePtr refresh;
|
||||||
CARD16 vRefresh;
|
CARD16 vRefresh;
|
||||||
|
@ -500,11 +500,14 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
||||||
/*
|
/*
|
||||||
* find modes not yet listed
|
* 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;
|
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;
|
l = data->nsize;
|
||||||
size[l].id = data->nsize;
|
size[l].id = data->nsize;
|
||||||
|
@ -524,9 +527,12 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
||||||
/*
|
/*
|
||||||
* Find all modes with matching size
|
* 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 &&
|
if (mode->mode.width == size[l].width &&
|
||||||
mode->mode.height == size[l].height)
|
mode->mode.height == size[l].height)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue