Split out 1.0-style info and new property routines to their own files.
This commit is contained in:
parent
7f9b59d80d
commit
cd63e82aa5
|
@ -12,7 +12,9 @@ librandr_la_SOURCES = \
|
|||
randrstr.h \
|
||||
rrcrtc.c \
|
||||
rrdispatch.c \
|
||||
rrinfo.c \
|
||||
rrmode.c \
|
||||
rroutput.c \
|
||||
rrproperty.c \
|
||||
rrscreen.c \
|
||||
rrsdispatch.c
|
||||
|
|
|
@ -108,11 +108,13 @@ miRandRInit (ScreenPtr pScreen)
|
|||
output = RROutputCreate (pScreen, "screen", 6, NULL);
|
||||
if (!output)
|
||||
return FALSE;
|
||||
if (!RROutputSet (output,
|
||||
NULL, 0, /* clones */
|
||||
&mode, 1, /* modes */
|
||||
&crtc, 1, /* crtcs */
|
||||
RR_Connected))
|
||||
if (!RROutputSetClones (output, NULL, 0))
|
||||
return FALSE;
|
||||
if (!RROutputSetModes (output, &mode, 1))
|
||||
return FALSE;
|
||||
if (!RROutputSetCrtcs (output, &crtc, 1))
|
||||
return FALSE;
|
||||
if (!RROutputSetConnection (output, RR_Connected))
|
||||
return FALSE;
|
||||
RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
|
||||
#endif
|
||||
|
|
394
randr/randr.c
394
randr/randr.c
|
@ -198,7 +198,9 @@ Bool RRScreenInit(ScreenPtr pScreen)
|
|||
pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height;
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
pScrPriv->rrCrtcSet = 0;
|
||||
pScrPriv->rrScreenSizeSet = NULL;
|
||||
pScrPriv->rrCrtcSet = NULL;
|
||||
pScrPriv->rrCrtcSetGamma = NULL;
|
||||
#endif
|
||||
#if RANDR_10_INTERFACE
|
||||
pScrPriv->rrSetConfig = 0;
|
||||
|
@ -400,196 +402,6 @@ RRFirstOutput (ScreenPtr pScreen)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef RANDR_10_INTERFACE
|
||||
static RRModePtr
|
||||
RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
|
||||
{
|
||||
ScreenPtr pScreen = output->pScreen;
|
||||
rrScrPriv(pScreen);
|
||||
xRRModeInfo modeInfo;
|
||||
char name[100];
|
||||
RRModePtr mode;
|
||||
int i;
|
||||
RRModePtr *modes;
|
||||
|
||||
memset (&modeInfo, '\0', sizeof (modeInfo));
|
||||
sprintf (name, "%dx%d", size->width, size->height);
|
||||
|
||||
modeInfo.width = size->width;
|
||||
modeInfo.height = size->height;
|
||||
modeInfo.mmWidth = size->mmWidth;
|
||||
modeInfo.mmHeight = size->mmHeight;
|
||||
modeInfo.hTotal = size->width;
|
||||
modeInfo.vTotal = size->height;
|
||||
modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->width *
|
||||
(CARD32) refresh);
|
||||
modeInfo.nameLength = strlen (name);
|
||||
mode = RRModeGet (pScreen, &modeInfo, name);
|
||||
if (!mode)
|
||||
return NULL;
|
||||
for (i = 0; i < output->numModes; i++)
|
||||
if (output->modes[i] == mode)
|
||||
{
|
||||
RRModeDestroy (mode);
|
||||
return mode;
|
||||
}
|
||||
|
||||
if (output->numModes)
|
||||
modes = xrealloc (output->modes,
|
||||
(output->numModes + 1) * sizeof (RRModePtr));
|
||||
else
|
||||
modes = xalloc (sizeof (RRModePtr));
|
||||
if (!modes)
|
||||
{
|
||||
RRModeDestroy (mode);
|
||||
FreeResource (mode->mode.id, 0);
|
||||
return NULL;
|
||||
}
|
||||
modes[output->numModes++] = mode;
|
||||
output->modes = modes;
|
||||
output->changed = TRUE;
|
||||
pScrPriv->changed = TRUE;
|
||||
return mode;
|
||||
}
|
||||
|
||||
static void
|
||||
RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
|
||||
{
|
||||
rrScrPriv(pScreen);
|
||||
RROutputPtr output;
|
||||
RRCrtcPtr crtc;
|
||||
RRModePtr mode, newMode = NULL;
|
||||
int i;
|
||||
CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT;
|
||||
CARD16 maxWidth = 0, maxHeight = 0;
|
||||
|
||||
/*
|
||||
* First time through, create a crtc and output and hook
|
||||
* them together
|
||||
*/
|
||||
if (pScrPriv->numOutputs == 0 &&
|
||||
pScrPriv->numCrtcs == 0)
|
||||
{
|
||||
crtc = RRCrtcCreate (pScreen, NULL);
|
||||
if (!crtc)
|
||||
return;
|
||||
output = RROutputCreate (pScreen, "default", 7, NULL);
|
||||
if (!output)
|
||||
return;
|
||||
RROutputSetCrtcs (output, &crtc, 1);
|
||||
RROutputSetCrtc (output, crtc);
|
||||
RROutputSetConnection (output, RR_Connected);
|
||||
#ifdef RENDER
|
||||
RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen));
|
||||
#endif
|
||||
}
|
||||
|
||||
output = RRFirstOutput (pScreen);
|
||||
if (!output)
|
||||
return;
|
||||
crtc = output->crtc;
|
||||
|
||||
/* check rotations */
|
||||
if (rotations != crtc->rotations)
|
||||
{
|
||||
crtc->rotations = rotations;
|
||||
crtc->changed = TRUE;
|
||||
pScrPriv->changed = TRUE;
|
||||
}
|
||||
|
||||
/* regenerate mode list */
|
||||
for (i = 0; i < pScrPriv->nSizes; i++)
|
||||
{
|
||||
RRScreenSizePtr size = &pScrPriv->pSizes[i];
|
||||
int r;
|
||||
|
||||
if (size->nRates)
|
||||
{
|
||||
for (r = 0; r < size->nRates; r++)
|
||||
{
|
||||
mode = RROldModeAdd (output, size, size->pRates[r].rate);
|
||||
if (i == pScrPriv->size &&
|
||||
size->pRates[r].rate == pScrPriv->rate)
|
||||
{
|
||||
newMode = mode;
|
||||
}
|
||||
}
|
||||
xfree (size->pRates);
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = RROldModeAdd (output, size, 0);
|
||||
if (i == pScrPriv->size)
|
||||
newMode = mode;
|
||||
}
|
||||
}
|
||||
if (pScrPriv->nSizes)
|
||||
xfree (pScrPriv->pSizes);
|
||||
pScrPriv->pSizes = NULL;
|
||||
pScrPriv->nSizes = 0;
|
||||
|
||||
/* find size bounds */
|
||||
for (i = 0; i < output->numModes; i++)
|
||||
{
|
||||
RRModePtr mode = output->modes[i];
|
||||
CARD16 width = mode->mode.width;
|
||||
CARD16 height = mode->mode.height;
|
||||
|
||||
if (width < minWidth) minWidth = width;
|
||||
if (width > maxWidth) maxWidth = width;
|
||||
if (height < minHeight) minHeight = height;
|
||||
if (height > maxHeight) maxHeight = height;
|
||||
}
|
||||
|
||||
if (minWidth != pScrPriv->minWidth) {
|
||||
pScrPriv->minWidth = minWidth; pScrPriv->changed = TRUE;
|
||||
}
|
||||
if (maxWidth != pScrPriv->maxWidth) {
|
||||
pScrPriv->maxWidth = maxWidth; pScrPriv->changed = TRUE;
|
||||
}
|
||||
if (minHeight != pScrPriv->minHeight) {
|
||||
pScrPriv->minHeight = minHeight; pScrPriv->changed = TRUE;
|
||||
}
|
||||
if (maxHeight != pScrPriv->maxHeight) {
|
||||
pScrPriv->maxHeight = maxHeight; pScrPriv->changed = TRUE;
|
||||
}
|
||||
|
||||
/* notice current mode */
|
||||
if (newMode)
|
||||
RRCrtcNotify (output->crtc, newMode, 0, 0, pScrPriv->rotation,
|
||||
1, &output);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Poll the driver for changed information
|
||||
*/
|
||||
Bool
|
||||
RRGetInfo (ScreenPtr pScreen)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
Rotation rotations;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pScrPriv->numOutputs; i++)
|
||||
pScrPriv->outputs[i]->changed = FALSE;
|
||||
for (i = 0; i < pScrPriv->numCrtcs; i++)
|
||||
pScrPriv->crtcs[i]->changed = FALSE;
|
||||
|
||||
rotations = 0;
|
||||
pScrPriv->changed = FALSE;
|
||||
|
||||
if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
|
||||
return FALSE;
|
||||
|
||||
#if RANDR_10_INTERFACE
|
||||
if (pScrPriv->nSizes)
|
||||
RRScanOldConfig (pScreen, rotations);
|
||||
#endif
|
||||
RRTellChanged (pScreen);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CARD16
|
||||
RRVerticalRefresh (xRRModeInfo *mode)
|
||||
{
|
||||
|
@ -602,83 +414,6 @@ RRVerticalRefresh (xRRModeInfo *mode)
|
|||
return (CARD16) refresh;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
RRSetScreenConfig (ScreenPtr pScreen,
|
||||
Rotation rotation,
|
||||
int rate,
|
||||
RRScreenSizePtr pSize)
|
||||
{
|
||||
rrScrPrivPtr pScrPriv;
|
||||
RRMonitorPtr pMonitor;
|
||||
short oldWidth, oldHeight;
|
||||
RRModePtr pMode;
|
||||
int status;
|
||||
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
||||
if (!pScrPriv)
|
||||
return BadImplementation;
|
||||
|
||||
pMonitor = pScrPriv->pMonitors;
|
||||
if (!pMonitor)
|
||||
return BadImplementation;
|
||||
|
||||
oldWidth = pScreen->width;
|
||||
oldHeight = pScreen->height;
|
||||
|
||||
if (!RRGetInfo (pScreen))
|
||||
return BadAlloc;
|
||||
|
||||
/*
|
||||
* Validate requested rotation
|
||||
*/
|
||||
|
||||
/* test the rotation bits only! */
|
||||
switch (rotation & 0xf) {
|
||||
case RR_Rotate_0:
|
||||
case RR_Rotate_90:
|
||||
case RR_Rotate_180:
|
||||
case RR_Rotate_270:
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Invalid rotation
|
||||
*/
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
if ((~pScrPriv->rotations) & rotation)
|
||||
{
|
||||
/*
|
||||
* requested rotation or reflection not supported by screen
|
||||
*/
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
for (pMode = pMonitor->pModes; pMode; pMode = pMode->next)
|
||||
{
|
||||
if (pMode->mode.width == pSize->width &&
|
||||
pMode->mode.height == pSize->height &&
|
||||
pMode->mode.widthInMillimeters == pSize->mmWidth &&
|
||||
pMode->mode.heightInMillimeters == pSize->mmHeight &&
|
||||
(RRVerticalRefresh (&pMode->mode) == rate || rate == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pMode)
|
||||
return BadValue;
|
||||
|
||||
status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0,
|
||||
rotation, currentTime);
|
||||
|
||||
if (status != RRSetConfigSuccess)
|
||||
return BadImplementation;
|
||||
return Success;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ProcRRDispatch (ClientPtr client)
|
||||
{
|
||||
|
@ -697,126 +432,3 @@ SProcRRDispatch (ClientPtr client)
|
|||
return (*SProcRandrVector[stuff->data]) (client);
|
||||
}
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
/*
|
||||
* Register the range of sizes for the screen
|
||||
*/
|
||||
void
|
||||
RRScreenSetSizeRange (ScreenPtr pScreen,
|
||||
CARD16 minWidth,
|
||||
CARD16 minHeight,
|
||||
CARD16 maxWidth,
|
||||
CARD16 maxHeight)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
|
||||
if (!pScrPriv)
|
||||
return;
|
||||
pScrPriv->minWidth = minWidth;
|
||||
pScrPriv->minHeight = minHeight;
|
||||
pScrPriv->maxWidth = maxWidth;
|
||||
pScrPriv->maxHeight = maxHeight;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RANDR_10_INTERFACE
|
||||
static Bool
|
||||
RRScreenSizeMatches (RRScreenSizePtr a,
|
||||
RRScreenSizePtr b)
|
||||
{
|
||||
if (a->width != b->width)
|
||||
return FALSE;
|
||||
if (a->height != b->height)
|
||||
return FALSE;
|
||||
if (a->mmWidth != b->mmWidth)
|
||||
return FALSE;
|
||||
if (a->mmHeight != b->mmHeight)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
RRScreenSizePtr
|
||||
RRRegisterSize (ScreenPtr pScreen,
|
||||
short width,
|
||||
short height,
|
||||
short mmWidth,
|
||||
short mmHeight)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
int i;
|
||||
RRScreenSize tmp;
|
||||
RRScreenSizePtr pNew;
|
||||
|
||||
if (!pScrPriv)
|
||||
return 0;
|
||||
|
||||
tmp.id = 0;
|
||||
tmp.width = width;
|
||||
tmp.height= height;
|
||||
tmp.mmWidth = mmWidth;
|
||||
tmp.mmHeight = mmHeight;
|
||||
tmp.pRates = 0;
|
||||
tmp.nRates = 0;
|
||||
for (i = 0; i < pScrPriv->nSizes; i++)
|
||||
if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
|
||||
return &pScrPriv->pSizes[i];
|
||||
pNew = xrealloc (pScrPriv->pSizes,
|
||||
(pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
|
||||
if (!pNew)
|
||||
return 0;
|
||||
pNew[pScrPriv->nSizes++] = tmp;
|
||||
pScrPriv->pSizes = pNew;
|
||||
return &pNew[pScrPriv->nSizes-1];
|
||||
}
|
||||
|
||||
Bool RRRegisterRate (ScreenPtr pScreen,
|
||||
RRScreenSizePtr pSize,
|
||||
int rate)
|
||||
{
|
||||
rrScrPriv(pScreen);
|
||||
int i;
|
||||
RRScreenRatePtr pNew, pRate;
|
||||
|
||||
if (!pScrPriv)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < pSize->nRates; i++)
|
||||
if (pSize->pRates[i].rate == rate)
|
||||
return TRUE;
|
||||
|
||||
pNew = xrealloc (pSize->pRates,
|
||||
(pSize->nRates + 1) * sizeof (RRScreenRate));
|
||||
if (!pNew)
|
||||
return FALSE;
|
||||
pRate = &pNew[pSize->nRates++];
|
||||
pRate->rate = rate;
|
||||
pSize->pRates = pNew;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Rotation
|
||||
RRGetRotation(ScreenPtr pScreen)
|
||||
{
|
||||
RROutputPtr output = RRFirstOutput (pScreen);
|
||||
|
||||
if (!output)
|
||||
return RR_Rotate_0;
|
||||
|
||||
return output->crtc->rotation;
|
||||
}
|
||||
|
||||
void
|
||||
RRSetCurrentConfig (ScreenPtr pScreen,
|
||||
Rotation rotation,
|
||||
int rate,
|
||||
RRScreenSizePtr pSize)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
|
||||
if (!pScrPriv)
|
||||
return;
|
||||
pScrPriv->size = pSize - pScrPriv->pSizes;
|
||||
pScrPriv->rotation = rotation;
|
||||
pScrPriv->rate = rate;
|
||||
}
|
||||
#endif
|
||||
|
|
128
randr/randrstr.h
128
randr/randrstr.h
|
@ -53,7 +53,7 @@
|
|||
|
||||
/* required for ABI compatibility for now */
|
||||
#define RANDR_10_INTERFACE 1
|
||||
/* #define RANDR_12_INTERFACE 1 */
|
||||
#define RANDR_12_INTERFACE 1
|
||||
|
||||
typedef XID RRMode;
|
||||
typedef XID RROutput;
|
||||
|
@ -89,6 +89,10 @@ struct _rrCrtc {
|
|||
Bool changed;
|
||||
int numOutputs;
|
||||
RROutputPtr *outputs;
|
||||
int gammaSize;
|
||||
CARD16 *gammaRed;
|
||||
CARD16 *gammaBlue;
|
||||
CARD16 *gammaGreen;
|
||||
void *devPrivate;
|
||||
};
|
||||
|
||||
|
@ -107,11 +111,12 @@ struct _rrOutput {
|
|||
int numModes;
|
||||
RRModePtr *modes;
|
||||
Bool changed;
|
||||
PropertyPtr properties;
|
||||
void *devPrivate;
|
||||
};
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
typedef Bool (*RRScreentSizeSetProcPtr) (ScreenPtr pScreen,
|
||||
typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
|
||||
CARD16 width,
|
||||
CARD16 height,
|
||||
CARD32 mmWidth,
|
||||
|
@ -125,6 +130,10 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
|
|||
Rotation rotation,
|
||||
int numOutputs,
|
||||
RROutputPtr *outputs);
|
||||
|
||||
typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen,
|
||||
RRCrtcPtr crtc);
|
||||
|
||||
#endif
|
||||
|
||||
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
|
||||
|
@ -167,6 +176,7 @@ typedef struct _rrScrPriv {
|
|||
#if RANDR_12_INTERFACE
|
||||
RRScreenSetSizeProcPtr rrScreenSizeSet;
|
||||
RRCrtcSetProcPtr rrCrtcSet;
|
||||
RRCrtcSetGammaProcPtr rrCrtcSetGamma;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -245,6 +255,16 @@ extern RESTYPE RRClientType, RREventType; /* resource types for event masks */
|
|||
extern int RRClientPrivateIndex;
|
||||
extern RESTYPE RRCrtcType, RRModeType, RROutputType;
|
||||
|
||||
#define LookupOutput(client,id,a) ((RROutputPtr) \
|
||||
(SecurityLookupIDByType (client, id, \
|
||||
RROutputType, a)))
|
||||
#define LookupCrtc(client,id,a) ((RRCrtcPtr) \
|
||||
(SecurityLookupIDByType (client, id, \
|
||||
RRCrtcType, a)))
|
||||
#define LookupMode(client,id,a) ((RRModePtr) \
|
||||
(SecurityLookupIDByType (client, id, \
|
||||
RRModeType, a)))
|
||||
|
||||
#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
|
||||
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
|
||||
|
||||
|
@ -283,6 +303,24 @@ RRScreenSizeSet (ScreenPtr pScreen,
|
|||
CARD32 mmWidth,
|
||||
CARD32 mmHeight);
|
||||
|
||||
/*
|
||||
* screen dispatch
|
||||
*/
|
||||
int
|
||||
ProcRRGetScreenSizeRange (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRSetScreenSize (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRGetScreenResources (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRSetScreenConfig (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRGetScreenInfo (ClientPtr client);
|
||||
|
||||
/*
|
||||
* Deliver a ScreenNotify event
|
||||
*/
|
||||
|
@ -413,6 +451,33 @@ RRCrtcSet (RRCrtcPtr crtc,
|
|||
int numOutput,
|
||||
RROutputPtr *outputs);
|
||||
|
||||
/*
|
||||
* Request that the Crtc gamma be changed
|
||||
*/
|
||||
|
||||
Bool
|
||||
RRCrtcGammaSet (RRCrtcPtr crtc,
|
||||
CARD16 *red,
|
||||
CARD16 *green,
|
||||
CARD16 *blue);
|
||||
|
||||
/*
|
||||
* Notify the extension that the Crtc gamma has been changed
|
||||
* The driver calls this whenever it has changed the gamma values
|
||||
* in the RRCrtcRec
|
||||
*/
|
||||
|
||||
Bool
|
||||
RRCrtcGammaNotify (RRCrtcPtr crtc);
|
||||
|
||||
/*
|
||||
* Set the size of the gamma table at server startup time
|
||||
*/
|
||||
|
||||
Bool
|
||||
RRCrtcGammaSetSize (RRCrtcPtr crtc,
|
||||
int size);
|
||||
|
||||
/*
|
||||
* Destroy a Crtc at shutdown
|
||||
*/
|
||||
|
@ -425,6 +490,25 @@ RRCrtcDestroy (RRCrtcPtr crtc);
|
|||
Bool
|
||||
RRCrtcInit (void);
|
||||
|
||||
/*
|
||||
* Crtc dispatch
|
||||
*/
|
||||
|
||||
int
|
||||
ProcRRGetCrtcInfo (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRSetCrtcConfig (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRGetCrtcGammaSize (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRGetCrtcGamma (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRSetCrtcGamma (ClientPtr client);
|
||||
|
||||
/* rrdispatch.c */
|
||||
Bool
|
||||
RRClientKnowsRates (ClientPtr pClient);
|
||||
|
@ -452,6 +536,18 @@ RRModeDestroy (RRModePtr mode);
|
|||
Bool
|
||||
RRModeInit (void);
|
||||
|
||||
int
|
||||
ProcRRCreateMode (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRDestroyMode (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRAddOutputMode (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRDeleteOutputMode (ClientPtr client);
|
||||
|
||||
/* rroutput.c */
|
||||
/*
|
||||
* Create an output
|
||||
|
@ -498,10 +594,38 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
|
|||
void
|
||||
RROutputDestroy (RROutputPtr output);
|
||||
|
||||
int
|
||||
ProcRRGetOutputInfo (ClientPtr client);
|
||||
|
||||
/*
|
||||
* Initialize output type
|
||||
*/
|
||||
Bool
|
||||
RROutputInit (void);
|
||||
|
||||
/* rrproperty.c */
|
||||
|
||||
void
|
||||
RRDeleteAllOutputProperties (RROutputPtr output);
|
||||
|
||||
void
|
||||
RRDeleteOutputProperty (RROutputPtr output, Atom property);
|
||||
|
||||
int
|
||||
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
|
||||
int format, int mode, unsigned long len,
|
||||
pointer value, Bool sendevent);
|
||||
|
||||
int
|
||||
ProcRRChangeOutputProperty (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRGetOutputProperty (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRListOutputProperties (ClientPtr client);
|
||||
|
||||
int
|
||||
ProcRRDeleteOutputProperty (ClientPtr client);
|
||||
|
||||
#endif /* _RANDRSTR_H_ */
|
||||
|
|
461
randr/rrcrtc.c
461
randr/rrcrtc.c
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "randrstr.h"
|
||||
#include "swaprep.h"
|
||||
|
||||
RESTYPE RRCrtcType;
|
||||
|
||||
|
@ -57,6 +58,8 @@ RRCrtcCreate (ScreenPtr pScreen,
|
|||
crtc->rotations = RR_Rotate_0;
|
||||
crtc->outputs = NULL;
|
||||
crtc->numOutputs = 0;
|
||||
crtc->gammaSize = 0;
|
||||
crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
|
||||
crtc->changed = TRUE;
|
||||
crtc->devPrivate = devPrivate;
|
||||
|
||||
|
@ -241,10 +244,74 @@ RRCrtcDestroyResource (pointer value, XID pid)
|
|||
break;
|
||||
}
|
||||
}
|
||||
free (value);
|
||||
if (crtc->gammaRed)
|
||||
xfree (crtc->gammaRed);
|
||||
xfree (value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Request that the Crtc gamma be changed
|
||||
*/
|
||||
|
||||
Bool
|
||||
RRCrtcGammaSet (RRCrtcPtr crtc,
|
||||
CARD16 *red,
|
||||
CARD16 *green,
|
||||
CARD16 *blue)
|
||||
{
|
||||
Bool ret = TRUE;
|
||||
#if RANDR_12_INTERFACE
|
||||
ScreenPtr pScreen = crtc->pScreen;
|
||||
rrScrPriv(pScreen);
|
||||
#endif
|
||||
|
||||
memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16));
|
||||
memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16));
|
||||
memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16));
|
||||
#if RANDR_12_INTERFACE
|
||||
if (pScrPriv->rrCrtcSetGamma)
|
||||
ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the extension that the Crtc gamma has been changed
|
||||
* The driver calls this whenever it has changed the gamma values
|
||||
* in the RRCrtcRec
|
||||
*/
|
||||
|
||||
Bool
|
||||
RRCrtcGammaNotify (RRCrtcPtr crtc)
|
||||
{
|
||||
return TRUE; /* not much going on here */
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the size of the gamma table at server startup time
|
||||
*/
|
||||
|
||||
Bool
|
||||
RRCrtcGammaSetSize (RRCrtcPtr crtc,
|
||||
int size)
|
||||
{
|
||||
CARD16 *gamma;
|
||||
|
||||
if (size == crtc->gammaSize)
|
||||
return TRUE;
|
||||
gamma = xalloc (size * 3 * sizeof (CARD16));
|
||||
if (!gamma)
|
||||
return FALSE;
|
||||
if (crtc->gammaRed)
|
||||
xfree (crtc->gammaRed);
|
||||
crtc->gammaRed = gamma;
|
||||
crtc->gammaGreen = gamma + size;
|
||||
crtc->gammaBlue = gamma + size*2;
|
||||
crtc->gammaSize = size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize crtc type
|
||||
*/
|
||||
|
@ -259,3 +326,395 @@ RRCrtcInit (void)
|
|||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRGetCrtcInfo (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRGetCrtcInfoReq);;
|
||||
xRRGetCrtcInfoReply rep;
|
||||
RRCrtcPtr crtc;
|
||||
CARD8 *extra;
|
||||
unsigned long extraLen;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
RRModePtr mode;
|
||||
RROutput *outputs;
|
||||
RROutput *possible;
|
||||
int i, j, k, n;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
|
||||
crtc = LookupCrtc(client, stuff->crtc, SecurityReadAccess);
|
||||
|
||||
if (!crtc)
|
||||
return RRErrorBase + BadRRCrtc;
|
||||
|
||||
pScreen = crtc->pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
||||
mode = crtc->mode;
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.status = RRSetConfigSuccess;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
|
||||
rep.x = crtc->x;
|
||||
rep.y = crtc->y;
|
||||
rep.width = mode ? mode->mode.width : 0;
|
||||
rep.height = mode ? mode->mode.height : 0;
|
||||
rep.mode = mode->mode.id;
|
||||
rep.rotation = crtc->rotation;
|
||||
rep.rotations = crtc->rotations;
|
||||
rep.nOutput = crtc->numOutputs;
|
||||
k = 0;
|
||||
for (i = 0; i < pScrPriv->numOutputs; i++)
|
||||
for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
|
||||
if (pScrPriv->outputs[i]->crtcs[j] == crtc)
|
||||
k++;
|
||||
rep.nPossibleOutput = k;
|
||||
|
||||
rep.length = rep.nOutput + rep.nPossibleOutput;
|
||||
|
||||
extraLen = rep.length << 2;
|
||||
extra = xalloc (extraLen);
|
||||
if (!extra)
|
||||
return BadAlloc;
|
||||
|
||||
outputs = (RROutput *) extra;
|
||||
possible = (RROutput *) (outputs + rep.nOutput);
|
||||
|
||||
for (i = 0; i < crtc->numOutputs; i++)
|
||||
{
|
||||
outputs[i] = crtc->outputs[i]->id;
|
||||
if (client->swapped)
|
||||
swapl (&outputs[i], n);
|
||||
}
|
||||
k = 0;
|
||||
for (i = 0; i < pScrPriv->numOutputs; i++)
|
||||
for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
|
||||
if (pScrPriv->outputs[i]->crtcs[j] == crtc)
|
||||
{
|
||||
possible[k] = pScrPriv->outputs[i]->id;
|
||||
if (client->swapped)
|
||||
swapl (&possible[k], n);
|
||||
k++;
|
||||
}
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swapl(&rep.timestamp, n);
|
||||
swaps(&rep.x, n);
|
||||
swaps(&rep.y, n);
|
||||
swaps(&rep.width, n);
|
||||
swaps(&rep.height, n);
|
||||
swapl(&rep.mode, n);
|
||||
swaps(&rep.rotation, n);
|
||||
swaps(&rep.rotations, n);
|
||||
swaps(&rep.nOutput, n);
|
||||
swaps(&rep.nPossibleOutput, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep);
|
||||
if (extraLen)
|
||||
{
|
||||
WriteToClient (client, extraLen, (char *) extra);
|
||||
xfree (extra);
|
||||
}
|
||||
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRSetCrtcConfig (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRSetCrtcConfigReq);
|
||||
xRRSetCrtcConfigReply rep;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
RRCrtcPtr crtc;
|
||||
RRModePtr mode;
|
||||
int numOutputs;
|
||||
RROutputPtr *outputs = NULL;
|
||||
RROutput *outputIds;
|
||||
TimeStamp configTime;
|
||||
TimeStamp time;
|
||||
Rotation rotation;
|
||||
int i, j;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
|
||||
numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2);
|
||||
|
||||
crtc = LookupIDByType (stuff->crtc, RRCrtcType);
|
||||
if (!crtc)
|
||||
{
|
||||
client->errorValue = stuff->crtc;
|
||||
return RRErrorBase + BadRRCrtc;
|
||||
}
|
||||
if (stuff->mode == None)
|
||||
{
|
||||
mode = NULL;
|
||||
if (numOutputs > 0)
|
||||
return BadMatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = LookupIDByType (stuff->mode, RRModeType);
|
||||
if (!mode)
|
||||
{
|
||||
client->errorValue = stuff->mode;
|
||||
return RRErrorBase + BadRRMode;
|
||||
}
|
||||
if (numOutputs == 0)
|
||||
return BadMatch;
|
||||
}
|
||||
outputs = xalloc (numOutputs * sizeof (RROutputPtr));
|
||||
if (!outputs)
|
||||
return BadAlloc;
|
||||
|
||||
outputIds = (RROutput *) (stuff + 1);
|
||||
for (i = 0; i < numOutputs; i++)
|
||||
{
|
||||
outputs[i] = LookupIDByType (outputIds[i], RROutputType);
|
||||
if (!outputs[i])
|
||||
{
|
||||
client->errorValue = outputIds[i];
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return RRErrorBase + BadRROutput;
|
||||
}
|
||||
/* validate crtc for this output */
|
||||
for (j = 0; j < outputs[i]->numCrtcs; j++)
|
||||
if (outputs[i]->crtcs[j] == crtc)
|
||||
break;
|
||||
if (j == outputs[j]->numCrtcs)
|
||||
{
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return BadMatch;
|
||||
}
|
||||
/* validate mode for this output */
|
||||
for (j = 0; j < outputs[i]->numModes; j++)
|
||||
if (outputs[i]->modes[j] == mode)
|
||||
break;
|
||||
if (j == outputs[i]->numModes)
|
||||
{
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return BadMatch;
|
||||
}
|
||||
}
|
||||
|
||||
pScreen = crtc->pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
||||
if (!RRGetInfo (pScreen))
|
||||
{
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
time = ClientTimeToServerTime(stuff->timestamp);
|
||||
configTime = ClientTimeToServerTime(stuff->configTimestamp);
|
||||
|
||||
if (!pScrPriv)
|
||||
{
|
||||
time = currentTime;
|
||||
rep.status = RRSetConfigFailed;
|
||||
goto sendReply;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the client's config timestamp is not the same as the last config
|
||||
* timestamp, then the config information isn't up-to-date and
|
||||
* can't even be validated
|
||||
*/
|
||||
if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
|
||||
{
|
||||
rep.status = RRSetConfigInvalidConfigTime;
|
||||
goto sendReply;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate requested rotation
|
||||
*/
|
||||
rotation = (Rotation) stuff->rotation;
|
||||
|
||||
/* test the rotation bits only! */
|
||||
switch (rotation & 0xf) {
|
||||
case RR_Rotate_0:
|
||||
case RR_Rotate_90:
|
||||
case RR_Rotate_180:
|
||||
case RR_Rotate_270:
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Invalid rotation
|
||||
*/
|
||||
client->errorValue = stuff->rotation;
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
if ((~crtc->rotations) & rotation)
|
||||
{
|
||||
/*
|
||||
* requested rotation or reflection not supported by screen
|
||||
*/
|
||||
client->errorValue = stuff->rotation;
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
/*
|
||||
* Check screen size bounds if the DDX provides a 1.2 interface
|
||||
* for setting screen size. Else, assume the CrtcSet sets
|
||||
* the size along with the mode
|
||||
*/
|
||||
if (pScrPriv->rrScreenSizeSet)
|
||||
{
|
||||
if (stuff->x + mode->mode.width > pScreen->width)
|
||||
{
|
||||
client->errorValue = stuff->x;
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
if (stuff->y + mode->mode.height > pScreen->height)
|
||||
{
|
||||
client->errorValue = stuff->y;
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
return BadValue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure the requested set-time is not older than
|
||||
* the last set-time
|
||||
*/
|
||||
if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
|
||||
{
|
||||
rep.status = RRSetConfigInvalidTime;
|
||||
goto sendReply;
|
||||
}
|
||||
|
||||
rep.status = RRCrtcSet (crtc, mode, stuff->x, stuff->y,
|
||||
rotation, numOutputs, outputs);
|
||||
|
||||
sendReply:
|
||||
if (outputs)
|
||||
xfree (outputs);
|
||||
|
||||
rep.type = X_Reply;
|
||||
/* rep.status has already been filled in */
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds;
|
||||
|
||||
if (client->swapped)
|
||||
{
|
||||
int n;
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swapl(&rep.newTimestamp, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep);
|
||||
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRGetCrtcGammaSize (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRGetCrtcGammaSizeReq);
|
||||
xRRGetCrtcGammaSizeReply reply;
|
||||
RRCrtcPtr crtc;
|
||||
int n;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
|
||||
crtc = LookupCrtc (client, stuff->crtc, SecurityReadAccess);
|
||||
if (!crtc)
|
||||
return RRErrorBase + BadRRCrtc;
|
||||
|
||||
reply.type = X_Reply;
|
||||
reply.sequenceNumber = client->sequence;
|
||||
reply.length = 0;
|
||||
reply.size = crtc->gammaSize;
|
||||
if (client->swapped) {
|
||||
swaps (&reply.sequenceNumber, n);
|
||||
swapl (&reply.length, n);
|
||||
swaps (&reply.size, n);
|
||||
}
|
||||
WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply);
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRGetCrtcGamma (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRGetCrtcGammaReq);
|
||||
xRRGetCrtcGammaReply reply;
|
||||
RRCrtcPtr crtc;
|
||||
int n;
|
||||
unsigned long len;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
|
||||
crtc = LookupCrtc (client, stuff->crtc, SecurityReadAccess);
|
||||
if (!crtc)
|
||||
return RRErrorBase + BadRRCrtc;
|
||||
|
||||
len = crtc->gammaSize * 3 * 2;
|
||||
|
||||
reply.type = X_Reply;
|
||||
reply.sequenceNumber = client->sequence;
|
||||
reply.length = (len + 3) >> 2;
|
||||
reply.size = crtc->gammaSize;
|
||||
if (client->swapped) {
|
||||
swaps (&reply.sequenceNumber, n);
|
||||
swapl (&reply.length, n);
|
||||
swaps (&reply.size, n);
|
||||
}
|
||||
WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply);
|
||||
if (crtc->gammaSize)
|
||||
{
|
||||
client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write;
|
||||
WriteSwappedDataToClient (client, len, (char *) crtc->gammaRed);
|
||||
}
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRSetCrtcGamma (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRSetCrtcGammaReq);
|
||||
RRCrtcPtr crtc;
|
||||
unsigned long len;
|
||||
CARD16 *red, *green, *blue;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRSetCrtcGammaReq);
|
||||
crtc = LookupCrtc (client, stuff->crtc, SecurityWriteAccess);
|
||||
if (!crtc)
|
||||
return RRErrorBase + BadRRCrtc;
|
||||
|
||||
len = client->req_len - (sizeof (xRRSetCrtcGammaReq) >> 2);
|
||||
if (len < (stuff->size * 3 + 1) >> 1)
|
||||
return BadLength;
|
||||
|
||||
if (stuff->size != crtc->gammaSize)
|
||||
return BadMatch;
|
||||
|
||||
red = (CARD16 *) (stuff + 1);
|
||||
green = red + crtc->gammaSize;
|
||||
blue = green + crtc->gammaSize;
|
||||
|
||||
RRCrtcGammaSet (crtc, red, green, blue);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
1035
randr/rrdispatch.c
1035
randr/rrdispatch.c
File diff suppressed because it is too large
Load Diff
|
@ -103,3 +103,44 @@ RRModeInit (void)
|
|||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRCreateMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRCreateModeReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRCreateModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRDestroyMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRDestroyModeReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRDestroyModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRAddOutputMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRAddOutputModeReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRDeleteOutputMode (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRDeleteOutputModeReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
|
||||
(void) stuff;
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ RROutputCreate (ScreenPtr pScreen,
|
|||
output->clones = NULL;
|
||||
output->numModes = 0;
|
||||
output->modes = NULL;
|
||||
output->properties = NULL;
|
||||
output->changed = TRUE;
|
||||
output->devPrivate = devPrivate;
|
||||
|
||||
|
@ -201,12 +202,13 @@ RROutputDestroyResource (pointer value, XID pid)
|
|||
xfree (output->crtcs);
|
||||
if (output->clones)
|
||||
xfree (output->clones);
|
||||
RRDeleteAllOutputProperties (output);
|
||||
xfree (output);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize crtc type
|
||||
* Initialize output type
|
||||
*/
|
||||
Bool
|
||||
RROutputInit (void)
|
||||
|
@ -219,3 +221,95 @@ RROutputInit (void)
|
|||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRGetOutputInfo (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRGetOutputInfoReq);;
|
||||
xRRGetOutputInfoReply rep;
|
||||
RROutputPtr output;
|
||||
CARD8 *extra;
|
||||
unsigned long extraLen;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
RRCrtc *crtcs;
|
||||
RRMode *modes;
|
||||
RROutput *clones;
|
||||
char *name;
|
||||
int i, n;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
|
||||
output = LookupOutput(client, stuff->output, SecurityReadAccess);
|
||||
|
||||
if (!output)
|
||||
return RRErrorBase + BadRROutput;
|
||||
|
||||
pScreen = output->pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
|
||||
rep.crtc = output->crtc ? output->crtc->id : None;
|
||||
rep.connection = output->connection;
|
||||
rep.subpixelOrder = output->subpixelOrder;
|
||||
rep.nCrtcs = output->numCrtcs;
|
||||
rep.nModes = output->numModes;
|
||||
rep.nClones = output->numClones;
|
||||
rep.nameLength = output->nameLength;
|
||||
|
||||
rep.length = (output->numCrtcs +
|
||||
output->numModes +
|
||||
output->numClones +
|
||||
((rep.nameLength + 3) >> 2));
|
||||
|
||||
extraLen = rep.length << 2;
|
||||
extra = xalloc (extraLen);
|
||||
if (!extra)
|
||||
return BadAlloc;
|
||||
|
||||
crtcs = (RRCrtc *) extra;
|
||||
modes = (RRMode *) (crtcs + output->numCrtcs);
|
||||
clones = (RROutput *) (modes + output->numModes);
|
||||
name = (char *) (clones + output->numClones);
|
||||
|
||||
for (i = 0; i < output->numCrtcs; i++)
|
||||
{
|
||||
crtcs[i] = output->crtcs[i]->id;
|
||||
if (client->swapped)
|
||||
swapl (&crtcs[i], n);
|
||||
}
|
||||
for (i = 0; i < output->numModes; i++)
|
||||
{
|
||||
modes[i] = output->modes[i]->mode.id;
|
||||
if (client->swapped)
|
||||
swapl (&modes[i], n);
|
||||
}
|
||||
for (i = 0; i < output->numClones; i++)
|
||||
{
|
||||
clones[i] = output->clones[i]->id;
|
||||
if (client->swapped)
|
||||
swapl (&clones[i], n);
|
||||
}
|
||||
memcpy (name, output->name, output->nameLength);
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swapl(&rep.timestamp, n);
|
||||
swapl(&rep.crtc, n);
|
||||
swaps(&rep.nCrtcs, n);
|
||||
swaps(&rep.nModes, n);
|
||||
swaps(&rep.nClones, n);
|
||||
swaps(&rep.nameLength, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep);
|
||||
if (extraLen)
|
||||
{
|
||||
WriteToClient (client, extraLen, (char *) extra);
|
||||
xfree (extra);
|
||||
}
|
||||
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
|
|
651
randr/rrscreen.c
651
randr/rrscreen.c
|
@ -203,3 +203,654 @@ RRScreenSizeSet (ScreenPtr pScreen,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve valid screen size range
|
||||
*/
|
||||
int
|
||||
ProcRRGetScreenSizeRange (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRGetScreenSizeRangeReq);
|
||||
xRRGetScreenSizeRangeReply rep;
|
||||
WindowPtr pWin;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
|
||||
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
|
||||
SecurityReadAccess);
|
||||
|
||||
if (!pWin)
|
||||
return BadWindow;
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.pad = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
|
||||
if (pScrPriv)
|
||||
{
|
||||
RRGetInfo (pScreen);
|
||||
rep.minWidth = pScrPriv->minWidth;
|
||||
rep.minHeight = pScrPriv->minHeight;
|
||||
rep.maxWidth = pScrPriv->maxWidth;
|
||||
rep.maxHeight = pScrPriv->maxHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
rep.maxWidth = rep.minWidth = pScreen->width;
|
||||
rep.maxHeight = rep.minHeight = pScreen->height;
|
||||
}
|
||||
if (client->swapped)
|
||||
{
|
||||
int n;
|
||||
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swaps(&rep.minWidth, n);
|
||||
swaps(&rep.minHeight, n);
|
||||
swaps(&rep.maxWidth, n);
|
||||
swaps(&rep.maxHeight, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRSetScreenSize (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRSetScreenSizeReq);
|
||||
WindowPtr pWin;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
RRCrtcPtr crtc;
|
||||
int i;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
|
||||
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
|
||||
SecurityReadAccess);
|
||||
|
||||
if (!pWin)
|
||||
return BadWindow;
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width)
|
||||
{
|
||||
client->errorValue = stuff->width;
|
||||
return BadValue;
|
||||
}
|
||||
if (stuff->height < pScrPriv->minHeight ||
|
||||
pScrPriv->maxHeight < stuff->height)
|
||||
{
|
||||
client->errorValue = stuff->height;
|
||||
return BadValue;
|
||||
}
|
||||
for (i = 0; i < pScrPriv->numCrtcs; i++) {
|
||||
crtc = pScrPriv->crtcs[i];
|
||||
if (crtc->mode &&
|
||||
(crtc->x + crtc->mode->mode.width > stuff->width ||
|
||||
crtc->y + crtc->mode->mode.height > stuff->height))
|
||||
return BadMatch;
|
||||
}
|
||||
if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
|
||||
{
|
||||
client->errorValue = 0;
|
||||
return BadValue;
|
||||
}
|
||||
if (!RRScreenSizeSet (pScreen,
|
||||
stuff->width, stuff->height,
|
||||
stuff->widthInMillimeters,
|
||||
stuff->heightInMillimeters))
|
||||
{
|
||||
return BadMatch;
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRGetScreenResources (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRGetScreenResourcesReq);
|
||||
xRRGetScreenResourcesReply rep;
|
||||
WindowPtr pWin;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
CARD8 *extra;
|
||||
unsigned long extraLen;
|
||||
int i;
|
||||
RRCrtc *crtcs;
|
||||
RROutput *outputs;
|
||||
xRRModeInfo *modeinfos;
|
||||
CARD8 *names;
|
||||
int n;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
|
||||
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
|
||||
SecurityReadAccess);
|
||||
|
||||
if (!pWin)
|
||||
return BadWindow;
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
rep.pad = 0;
|
||||
|
||||
if (pScrPriv)
|
||||
RRGetInfo (pScreen);
|
||||
|
||||
if (!pScrPriv)
|
||||
{
|
||||
rep.type = X_Reply;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.timestamp = currentTime.milliseconds;
|
||||
rep.configTimestamp = currentTime.milliseconds;
|
||||
rep.nCrtcs = 0;
|
||||
rep.nOutputs = 0;
|
||||
rep.nModes = 0;
|
||||
rep.nbytesNames = 0;
|
||||
extra = NULL;
|
||||
extraLen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rep.type = X_Reply;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.timestamp = currentTime.milliseconds;
|
||||
rep.configTimestamp = currentTime.milliseconds;
|
||||
rep.nCrtcs = pScrPriv->numCrtcs;
|
||||
rep.nOutputs = pScrPriv->numOutputs;
|
||||
rep.nModes = pScrPriv->numModes;;
|
||||
rep.nbytesNames = 0;
|
||||
|
||||
for (i = 0; i < pScrPriv->numModes; i++)
|
||||
rep.nbytesNames += pScrPriv->modes[i]->mode.nameLength;
|
||||
|
||||
rep.length = (pScrPriv->numCrtcs +
|
||||
pScrPriv->numOutputs +
|
||||
pScrPriv->numModes * 10 +
|
||||
((rep.nbytesNames + 3) >> 2));
|
||||
|
||||
extraLen = rep.length << 2;
|
||||
extra = xalloc (extraLen);
|
||||
if (!extra)
|
||||
return BadAlloc;
|
||||
|
||||
crtcs = (RRCrtc *) extra;
|
||||
outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs);
|
||||
modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs);
|
||||
names = (CARD8 *) (modeinfos + pScrPriv->numModes);
|
||||
|
||||
for (i = 0; i < pScrPriv->numCrtcs; i++)
|
||||
{
|
||||
crtcs[i] = pScrPriv->crtcs[i]->id;
|
||||
if (client->swapped)
|
||||
swapl (&crtcs[i], n);
|
||||
}
|
||||
|
||||
for (i = 0; i < pScrPriv->numOutputs; i++)
|
||||
{
|
||||
outputs[i] = pScrPriv->outputs[i]->id;
|
||||
if (client->swapped)
|
||||
swapl (&outputs[i], n);
|
||||
}
|
||||
|
||||
for (i = 0; i < pScrPriv->numModes; i++)
|
||||
{
|
||||
modeinfos[i] = pScrPriv->modes[i]->mode;
|
||||
if (client->swapped)
|
||||
{
|
||||
swapl (&modeinfos[i].id, n);
|
||||
swaps (&modeinfos[i].width, n);
|
||||
swaps (&modeinfos[i].height, n);
|
||||
swapl (&modeinfos[i].mmWidth, n);
|
||||
swapl (&modeinfos[i].mmHeight, n);
|
||||
swapl (&modeinfos[i].dotClock, n);
|
||||
swaps (&modeinfos[i].hSyncStart, n);
|
||||
swaps (&modeinfos[i].hSyncEnd, n);
|
||||
swaps (&modeinfos[i].hTotal, n);
|
||||
swaps (&modeinfos[i].hSkew, n);
|
||||
swaps (&modeinfos[i].vSyncStart, n);
|
||||
swaps (&modeinfos[i].vSyncEnd, n);
|
||||
swaps (&modeinfos[i].vTotal, n);
|
||||
swaps (&modeinfos[i].nameLength, n);
|
||||
swapl (&modeinfos[i].modeFlags, n);
|
||||
}
|
||||
memcpy (names, pScrPriv->modes[i]->name,
|
||||
pScrPriv->modes[i]->mode.nameLength);
|
||||
names += pScrPriv->modes[i]->mode.nameLength;
|
||||
}
|
||||
assert ((names + 3 >> 3) == rep.length);
|
||||
}
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swapl(&rep.timestamp, n);
|
||||
swapl(&rep.configTimestamp, n);
|
||||
swaps(&rep.nCrtcs, n);
|
||||
swaps(&rep.nOutputs, n);
|
||||
swaps(&rep.nModes, n);
|
||||
swaps(&rep.nbytesNames, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *)&rep);
|
||||
if (extraLen)
|
||||
{
|
||||
WriteToClient (client, extraLen, (char *) extra);
|
||||
xfree (extra);
|
||||
}
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
typedef struct _RR10Data {
|
||||
RRScreenSizePtr sizes;
|
||||
int nsize;
|
||||
int nrefresh;
|
||||
int size;
|
||||
CARD16 refresh;
|
||||
} RR10DataRec, *RR10DataPtr;
|
||||
|
||||
/*
|
||||
* Convert 1.2 monitor data into 1.0 screen data
|
||||
*/
|
||||
static RR10DataPtr
|
||||
RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
||||
{
|
||||
RR10DataPtr data;
|
||||
RRScreenSizePtr size;
|
||||
int nmode = output->numModes;
|
||||
int i, j, k;
|
||||
RRScreenRatePtr refresh;
|
||||
CARD16 vRefresh;
|
||||
RRModePtr mode;
|
||||
|
||||
/* Make sure there is plenty of space for any combination */
|
||||
data = malloc (sizeof (RR10DataRec) +
|
||||
sizeof (RRScreenSize) * nmode +
|
||||
sizeof (RRScreenRate) * nmode);
|
||||
if (!data)
|
||||
return NULL;
|
||||
size = (RRScreenSizePtr) (data + 1);
|
||||
refresh = (RRScreenRatePtr) (size + nmode);
|
||||
data->sizes = size;
|
||||
data->nsize = 0;
|
||||
data->nrefresh = 0;
|
||||
data->size = 0;
|
||||
data->refresh = 0;
|
||||
for (i = 0; i < output->numModes; i++)
|
||||
{
|
||||
mode = output->modes[i];
|
||||
for (j = 0; j < data->nsize; j++)
|
||||
if (mode->mode.width == size[j].width &&
|
||||
mode->mode.height == size[j].height)
|
||||
break;
|
||||
if (j == data->nsize)
|
||||
{
|
||||
size[j].id = j;
|
||||
size[j].width = mode->mode.width;
|
||||
size[j].height = mode->mode.height;
|
||||
size[j].mmWidth = mode->mode.mmWidth;
|
||||
size[j].mmHeight = mode->mode.mmHeight;
|
||||
size[j].nRates = 0;
|
||||
size[j].pRates = &refresh[data->nrefresh];
|
||||
data->nsize++;
|
||||
}
|
||||
vRefresh = RRVerticalRefresh (&mode->mode);
|
||||
for (k = 0; k < size[j].nRates; k++)
|
||||
if (vRefresh == size[j].pRates[k].rate)
|
||||
break;
|
||||
if (k == size[j].nRates)
|
||||
{
|
||||
size[j].pRates[k].rate = vRefresh;
|
||||
size[j].pRates[k].mode = mode;
|
||||
size[j].nRates++;
|
||||
data->nrefresh++;
|
||||
}
|
||||
if (mode == output->crtc->mode)
|
||||
{
|
||||
data->size = j;
|
||||
data->refresh = vRefresh;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRGetScreenInfo (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRGetScreenInfoReq);
|
||||
xRRGetScreenInfoReply rep;
|
||||
WindowPtr pWin;
|
||||
int n;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
CARD8 *extra;
|
||||
unsigned long extraLen;
|
||||
RROutputPtr output;
|
||||
|
||||
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
|
||||
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
|
||||
SecurityReadAccess);
|
||||
|
||||
if (!pWin)
|
||||
return BadWindow;
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
rep.pad = 0;
|
||||
|
||||
if (pScrPriv)
|
||||
RRGetInfo (pScreen);
|
||||
|
||||
output = RRFirstOutput (pScreen);
|
||||
|
||||
if (!pScrPriv || !output)
|
||||
{
|
||||
rep.type = X_Reply;
|
||||
rep.setOfRotations = RR_Rotate_0;;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
|
||||
rep.timestamp = currentTime.milliseconds;
|
||||
rep.configTimestamp = currentTime.milliseconds;
|
||||
rep.nSizes = 0;
|
||||
rep.sizeID = 0;
|
||||
rep.rotation = RR_Rotate_0;
|
||||
rep.rate = 0;
|
||||
rep.nrateEnts = 0;
|
||||
extra = 0;
|
||||
extraLen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, j;
|
||||
xScreenSizes *size;
|
||||
CARD16 *rates;
|
||||
CARD8 *data8;
|
||||
Bool has_rate = RRClientKnowsRates (client);
|
||||
RR10DataPtr pData;
|
||||
RRScreenSizePtr pSize;
|
||||
|
||||
pData = RR10GetData (pScreen, output);
|
||||
if (!pData)
|
||||
return BadAlloc;
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.setOfRotations = output->crtc->rotations;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
|
||||
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
|
||||
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
|
||||
rep.rotation = output->crtc->rotation;
|
||||
rep.nSizes = pData->nsize;
|
||||
rep.nrateEnts = pData->nrefresh + pData->nsize;
|
||||
rep.sizeID = pData->size;
|
||||
rep.rate = pData->refresh;
|
||||
|
||||
extraLen = (rep.nSizes * sizeof (xScreenSizes) +
|
||||
rep.nrateEnts * sizeof (CARD16));
|
||||
|
||||
extra = (CARD8 *) xalloc (extraLen);
|
||||
if (!extra)
|
||||
{
|
||||
xfree (pData);
|
||||
return BadAlloc;
|
||||
}
|
||||
/*
|
||||
* First comes the size information
|
||||
*/
|
||||
size = (xScreenSizes *) extra;
|
||||
rates = (CARD16 *) (size + rep.nSizes);
|
||||
for (i = 0; i < pData->nsize; i++)
|
||||
{
|
||||
pSize = &pData->sizes[i];
|
||||
size->widthInPixels = pSize->width;
|
||||
size->heightInPixels = pSize->height;
|
||||
size->widthInMillimeters = pSize->mmWidth;
|
||||
size->heightInMillimeters = pSize->mmHeight;
|
||||
if (client->swapped)
|
||||
{
|
||||
swaps (&size->widthInPixels, n);
|
||||
swaps (&size->heightInPixels, n);
|
||||
swaps (&size->widthInMillimeters, n);
|
||||
swaps (&size->heightInMillimeters, n);
|
||||
}
|
||||
size++;
|
||||
if (has_rate)
|
||||
{
|
||||
*rates = pSize->nRates;
|
||||
if (client->swapped)
|
||||
{
|
||||
swaps (rates, n);
|
||||
}
|
||||
rates++;
|
||||
for (j = 0; j < pSize->nRates; j++)
|
||||
{
|
||||
*rates = pSize->pRates[j].rate;
|
||||
if (client->swapped)
|
||||
{
|
||||
swaps (rates, n);
|
||||
}
|
||||
rates++;
|
||||
}
|
||||
}
|
||||
}
|
||||
xfree (pData);
|
||||
|
||||
data8 = (CARD8 *) rates;
|
||||
|
||||
if (data8 - (CARD8 *) extra != extraLen)
|
||||
FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
|
||||
(unsigned long)(data8 - (CARD8 *) extra), extraLen);
|
||||
rep.length = (extraLen + 3) >> 2;
|
||||
}
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swapl(&rep.timestamp, n);
|
||||
swaps(&rep.rotation, n);
|
||||
swaps(&rep.nSizes, n);
|
||||
swaps(&rep.sizeID, n);
|
||||
swaps(&rep.rate, n);
|
||||
swaps(&rep.nrateEnts, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
|
||||
if (extraLen)
|
||||
{
|
||||
WriteToClient (client, extraLen, (char *) extra);
|
||||
xfree (extra);
|
||||
}
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
int
|
||||
ProcRRSetScreenConfig (ClientPtr client)
|
||||
{
|
||||
REQUEST(xRRSetScreenConfigReq);
|
||||
xRRSetScreenConfigReply rep;
|
||||
DrawablePtr pDraw;
|
||||
int n;
|
||||
ScreenPtr pScreen;
|
||||
rrScrPrivPtr pScrPriv;
|
||||
TimeStamp configTime;
|
||||
TimeStamp time;
|
||||
int i;
|
||||
Rotation rotation;
|
||||
int rate;
|
||||
Bool has_rate;
|
||||
RROutputPtr output;
|
||||
RRModePtr mode;
|
||||
RR10DataPtr pData = NULL;
|
||||
RRScreenSizePtr pSize;
|
||||
|
||||
UpdateCurrentTime ();
|
||||
|
||||
if (RRClientKnowsRates (client))
|
||||
{
|
||||
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
|
||||
has_rate = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
|
||||
has_rate = FALSE;
|
||||
}
|
||||
|
||||
SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
|
||||
SecurityWriteAccess);
|
||||
|
||||
pScreen = pDraw->pScreen;
|
||||
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
|
||||
time = ClientTimeToServerTime(stuff->timestamp);
|
||||
configTime = ClientTimeToServerTime(stuff->configTimestamp);
|
||||
|
||||
if (!pScrPriv)
|
||||
{
|
||||
time = currentTime;
|
||||
rep.status = RRSetConfigFailed;
|
||||
goto sendReply;
|
||||
}
|
||||
if (!RRGetInfo (pScreen))
|
||||
return BadAlloc;
|
||||
|
||||
output = RRFirstOutput (pScreen);
|
||||
if (!output)
|
||||
{
|
||||
time = currentTime;
|
||||
rep.status = RRSetConfigFailed;
|
||||
goto sendReply;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the client's config timestamp is not the same as the last config
|
||||
* timestamp, then the config information isn't up-to-date and
|
||||
* can't even be validated
|
||||
*/
|
||||
if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
|
||||
{
|
||||
rep.status = RRSetConfigInvalidConfigTime;
|
||||
goto sendReply;
|
||||
}
|
||||
|
||||
pData = RR10GetData (pScreen, output);
|
||||
if (!pData)
|
||||
return BadAlloc;
|
||||
|
||||
if (stuff->sizeID >= pData->nsize)
|
||||
{
|
||||
/*
|
||||
* Invalid size ID
|
||||
*/
|
||||
client->errorValue = stuff->sizeID;
|
||||
xfree (pData);
|
||||
return BadValue;
|
||||
}
|
||||
pSize = &pData->sizes[stuff->sizeID];
|
||||
|
||||
/*
|
||||
* Validate requested rotation
|
||||
*/
|
||||
rotation = (Rotation) stuff->rotation;
|
||||
|
||||
/* test the rotation bits only! */
|
||||
switch (rotation & 0xf) {
|
||||
case RR_Rotate_0:
|
||||
case RR_Rotate_90:
|
||||
case RR_Rotate_180:
|
||||
case RR_Rotate_270:
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Invalid rotation
|
||||
*/
|
||||
client->errorValue = stuff->rotation;
|
||||
xfree (pData);
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
if ((~output->crtc->rotations) & rotation)
|
||||
{
|
||||
/*
|
||||
* requested rotation or reflection not supported by screen
|
||||
*/
|
||||
client->errorValue = stuff->rotation;
|
||||
xfree (pData);
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate requested refresh
|
||||
*/
|
||||
if (has_rate)
|
||||
rate = (int) stuff->rate;
|
||||
else
|
||||
rate = 0;
|
||||
|
||||
if (rate)
|
||||
{
|
||||
for (i = 0; i < pSize->nRates; i++)
|
||||
{
|
||||
if (pSize->pRates[i].rate == rate)
|
||||
break;
|
||||
}
|
||||
if (i == pSize->nRates)
|
||||
{
|
||||
/*
|
||||
* Invalid rate
|
||||
*/
|
||||
client->errorValue = rate;
|
||||
xfree (pData);
|
||||
return BadValue;
|
||||
}
|
||||
mode = pSize->pRates[i].mode;
|
||||
}
|
||||
else
|
||||
mode = pSize->pRates[0].mode;
|
||||
|
||||
/*
|
||||
* Make sure the requested set-time is not older than
|
||||
* the last set-time
|
||||
*/
|
||||
if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
|
||||
{
|
||||
rep.status = RRSetConfigInvalidTime;
|
||||
goto sendReply;
|
||||
}
|
||||
|
||||
rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation,
|
||||
1, &output);
|
||||
|
||||
sendReply:
|
||||
|
||||
if (pData)
|
||||
xfree (pData);
|
||||
|
||||
rep.type = X_Reply;
|
||||
/* rep.status has already been filled in */
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
|
||||
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
|
||||
rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
|
||||
rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
|
||||
|
||||
if (client->swapped)
|
||||
{
|
||||
swaps(&rep.sequenceNumber, n);
|
||||
swapl(&rep.length, n);
|
||||
swapl(&rep.newTimestamp, n);
|
||||
swapl(&rep.newConfigTimestamp, n);
|
||||
swapl(&rep.root, n);
|
||||
}
|
||||
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user