RandR: New data structure, old API. At least it compiles now
This commit is contained in:
parent
d95c758630
commit
cab3a0145f
|
@ -65,11 +65,11 @@ miRRGetInfo (ScreenPtr pScreen, Rotation *rotations)
|
|||
rrMode.height = pScreen->height;
|
||||
rrMode.widthInMillimeters = pScreen->mmWidth;
|
||||
rrMode.heightInMillimeters = pScreen->mmHeight;
|
||||
pMonitor = RRRegisterMonitor (pScreen, RR_Rotate_0);
|
||||
rrMode.nameLength = strlen (name);
|
||||
pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0);
|
||||
pMode = RRRegisterMode (pMonitor,
|
||||
&rrMode,
|
||||
name,
|
||||
strlen (name));
|
||||
name);
|
||||
if (!pMode)
|
||||
return FALSE;
|
||||
if (!setConfig)
|
||||
|
@ -90,6 +90,8 @@ Bool
|
|||
miRRSetMode (ScreenPtr pScreen,
|
||||
int monitor,
|
||||
RRModePtr pMode,
|
||||
int x,
|
||||
int y,
|
||||
Rotation rotation)
|
||||
{
|
||||
return TRUE;
|
||||
|
|
659
randr/randr.c
659
randr/randr.c
|
@ -163,12 +163,12 @@ RRCloseScreen (int i, ScreenPtr pScreen)
|
|||
RRMonitorPtr pMonitor;
|
||||
|
||||
unwrap (pScrPriv, pScreen, CloseScreen);
|
||||
while (pMonitor = pScrPriv->pMonitors)
|
||||
while ((pMonitor = pScrPriv->pMonitors))
|
||||
{
|
||||
RRModePtr pMode;
|
||||
|
||||
pScrPriv->pMonitors = pMonitor->next;
|
||||
while (pMode = pMonitor->pModes)
|
||||
while ((pMode = pMonitor->pModes))
|
||||
{
|
||||
pMonitor->pModes = pMode->next;
|
||||
xfree (pMode);
|
||||
|
@ -218,6 +218,20 @@ SRRMonitorChangeNotifyEvent(xRRMonitorChangeNotifyEvent *from,
|
|||
cpswaps(from->y, to->y);
|
||||
}
|
||||
|
||||
static void
|
||||
SRRNotifyEvent (xEvent *from,
|
||||
xEvent *to)
|
||||
{
|
||||
switch (from->u.u.detail) {
|
||||
case RRNotify_MonitorChange:
|
||||
SRRMonitorChangeNotifyEvent ((xRRMonitorChangeNotifyEvent *) from,
|
||||
(xRRMonitorChangeNotifyEvent *) to);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bool RRScreenInit(ScreenPtr pScreen)
|
||||
{
|
||||
rrScrPrivPtr pScrPriv;
|
||||
|
@ -336,6 +350,8 @@ RRExtensionInit (void)
|
|||
RREventBase = extEntry->eventBase;
|
||||
EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
|
||||
SRRScreenChangeNotifyEvent;
|
||||
EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr)
|
||||
SRRNotifyEvent;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -349,8 +365,8 @@ TellChanged (WindowPtr pWin, pointer value)
|
|||
xRRMonitorChangeNotifyEvent me;
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
rrScrPriv(pScreen);
|
||||
RRMonitorPtr pMonitor = pScrPriv->pMonitors;
|
||||
RRModePtr pMode;
|
||||
RRMonitorPtr pMonitor;
|
||||
WindowPtr pRoot = WindowTable[pScreen->myNum];
|
||||
int i;
|
||||
|
||||
|
@ -364,7 +380,7 @@ TellChanged (WindowPtr pWin, pointer value)
|
|||
if (client == serverClient || client->clientGone)
|
||||
continue;
|
||||
|
||||
if (pRREvent->mask & RRMonitorChangeNotifyMask))
|
||||
if (pRREvent->mask & RRMonitorChangeNotifyMask)
|
||||
{
|
||||
me.type = RRNotify + RREventBase;
|
||||
me.subCode = RRNotify_MonitorChange;
|
||||
|
@ -377,12 +393,13 @@ TellChanged (WindowPtr pWin, pointer value)
|
|||
#else
|
||||
me.subpixelOrder = SubPixelUnknown;
|
||||
#endif
|
||||
for (i = 0; i < pScrPriv->nMonitors; i++)
|
||||
for (pMonitor = pScrPriv->pMonitors, i = 0;
|
||||
pMonitor;
|
||||
pMonitor = pMonitor->next, i++)
|
||||
{
|
||||
pMonitor = &pScrPriv->pMonitors[i];
|
||||
me.monitor = i;
|
||||
if (pMonitor->mode >= 0) {
|
||||
me.modeID = pMonitor->pMode[pMonitor->mode].id;
|
||||
if (pMonitor->pMode) {
|
||||
me.modeID = pMonitor->pMode->id;
|
||||
me.rotation = pMonitor->rotation;
|
||||
me.x = pMonitor->x;
|
||||
me.y = pMonitor->y;
|
||||
|
@ -396,10 +413,10 @@ TellChanged (WindowPtr pWin, pointer value)
|
|||
}
|
||||
}
|
||||
if ((pRREvent->mask & RRScreenChangeNotifyMask) &&
|
||||
pScrPriv->nMonitors > 0)
|
||||
(pMonitor = pScrPriv->pMonitors))
|
||||
{
|
||||
se.type = RRScreenChangeNotify + RREventBase;
|
||||
se.rotation = (CARD8) pScrPriv->rotation;
|
||||
se.rotation = (CARD8) pMonitor->rotation;
|
||||
se.timestamp = pScrPriv->lastSetTime.milliseconds;
|
||||
se.sequenceNumber = client->sequence;
|
||||
se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
|
||||
|
@ -413,14 +430,14 @@ TellChanged (WindowPtr pWin, pointer value)
|
|||
|
||||
pMonitor = &pScrPriv->pMonitors[0];
|
||||
se.sequenceNumber = client->sequence;
|
||||
if (pMonitor->mode >= 0)
|
||||
if (pMonitor->pMode)
|
||||
{
|
||||
pMode = &pMonitor->pModes[pMonitor->mode];
|
||||
pMode = pMonitor->pMode;
|
||||
se.sizeID = pMode->id;
|
||||
se.widthInPixels = pMode->width;
|
||||
se.heightInPixels = pMode->height;
|
||||
se.widthInMillimeters = pMode->mmWidth;
|
||||
se.heightInMillimeters = pMode->mmHeight;
|
||||
se.widthInPixels = pMode->mode.width;
|
||||
se.heightInPixels = pMode->mode.height;
|
||||
se.widthInMillimeters = pMode->mode.widthInMillimeters;
|
||||
se.heightInMillimeters = pMode->mode.heightInMillimeters;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -440,70 +457,107 @@ TellChanged (WindowPtr pWin, pointer value)
|
|||
return WT_WALKCHILDREN;
|
||||
}
|
||||
|
||||
static void
|
||||
RRFreeMode (RRModePtr pMode)
|
||||
{
|
||||
xfree (pMode);
|
||||
}
|
||||
|
||||
static void
|
||||
RRFreeModes (RRModePtr pHead)
|
||||
{
|
||||
RRModePtr pMode;
|
||||
while ((pMode = pHead))
|
||||
{
|
||||
pHead = pMode->next;
|
||||
RRFreeMode (pMode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
RRFreeMonitor (RRMonitorPtr pMonitor)
|
||||
{
|
||||
RRFreeModes (pMonitor->pModes);
|
||||
xfree (pMonitor);
|
||||
}
|
||||
|
||||
|
||||
static Bool
|
||||
RRGetInfo (ScreenPtr pScreen)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
int m, s, n;
|
||||
Bool changed;
|
||||
Rotation rotations;
|
||||
RRMonitorPtr pMonitor;
|
||||
RRModePtr pMode;
|
||||
RRMonitorPtr pMonitor, *pPrevMon;
|
||||
RRModePtr pMode, *pPrevMode;
|
||||
int monitorid;
|
||||
|
||||
for (m = 0; m < pScrPriv->nMonitors; m++)
|
||||
for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next)
|
||||
{
|
||||
pMonitor = &pScrPriv->pMonitors[m];
|
||||
pMonitor->oldReferenced = pMonitor->referenced;
|
||||
pMonitor->oldReferenced = TRUE;
|
||||
pMonitor->referenced = FALSE;
|
||||
for (s = 0; s < pMonitor->nModes; s++)
|
||||
pMonitor->pMode = NULL;
|
||||
for (pMode = pMonitor->pModes; pMode; pMode = pMode->next)
|
||||
{
|
||||
pMode = &pSize->pModes[s];
|
||||
pMode->oldReferenced = pMode->referenced;
|
||||
pMode->oldReferenced = TRUE;
|
||||
pMode->referenced = FALSE;
|
||||
}
|
||||
}
|
||||
changed = FALSE;
|
||||
|
||||
rotations = 0;
|
||||
if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
|
||||
return FALSE;
|
||||
|
||||
changed = FALSE;
|
||||
|
||||
/* Old GetInfo clients return rotations here */
|
||||
if (rotations && pScrPriv->nMonitors) {
|
||||
if (rotations && pScrPriv->pMonitors) {
|
||||
/*
|
||||
* Check whether anything changed and simultaneously generate
|
||||
* the protocol id values for the objects
|
||||
*/
|
||||
if (rotations != pScrPriv->pMonitors[i].rotations)
|
||||
if (rotations != pScrPriv->pMonitors->rotations)
|
||||
{
|
||||
pScrPriv->pMonitors[i].rotations = rotations;
|
||||
pScrPriv->pMonitors->rotations = rotations;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
n = 0;
|
||||
for (m = 0; m < pScrPriv->nMonitors; m++)
|
||||
/*
|
||||
* Walk monitor and mode lists looking for updates
|
||||
*/
|
||||
monitorid = 0;
|
||||
for (pPrevMon = &pScrPriv->pMonitors; (pMonitor = *pPrevMon);)
|
||||
{
|
||||
int modeid = 0;
|
||||
|
||||
pMonitor = &pScrPriv->pMonitors[m];
|
||||
if (pMonitor->oldReferenced != pMonitor->referenced)
|
||||
changed = TRUE;
|
||||
if (pMonitor->referenced)
|
||||
{
|
||||
for (s = 0; s < pMonitor->nModes; s++)
|
||||
{
|
||||
pMode = &pMonitor->pModes[s];
|
||||
if (pMode->oldReferenced != pMode->referenced)
|
||||
pMonitor->id = monitorid++;
|
||||
if (!pMonitor->oldReferenced)
|
||||
changed = TRUE;
|
||||
for (pPrevMode = &pMonitor->pModes; (pMode = *pPrevMode);)
|
||||
{
|
||||
if (pMode->referenced)
|
||||
{
|
||||
pMode->id = modeid++;
|
||||
if (!pMode->oldReferenced)
|
||||
changed = TRUE;
|
||||
}
|
||||
n++;
|
||||
else
|
||||
{
|
||||
*pPrevMode = pMode->next;
|
||||
changed = TRUE;
|
||||
RRFreeMode (pMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pPrevMon = pMonitor->next;
|
||||
changed = TRUE;
|
||||
RRFreeMonitor (pMonitor);
|
||||
}
|
||||
pMonitor->nModesInUse = modeid;
|
||||
}
|
||||
pScrPriv->nMonitorsInUse = n;
|
||||
if (changed)
|
||||
{
|
||||
UpdateCurrentTime ();
|
||||
|
@ -548,6 +602,10 @@ ProcRRQueryVersion (ClientPtr client)
|
|||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
/*
|
||||
* Report the current version; the current
|
||||
* spec says they're all compatible after 1.0
|
||||
*/
|
||||
rep.majorVersion = RANDR_MAJOR;
|
||||
rep.minorVersion = RANDR_MINOR;
|
||||
if (client->swapped) {
|
||||
|
@ -604,6 +662,100 @@ RREditConnectionInfo (ScreenPtr pScreen)
|
|||
root->mmHeight = pScreen->mmHeight;
|
||||
}
|
||||
|
||||
static int
|
||||
RRNumModes (RRMonitorPtr pMonitor)
|
||||
{
|
||||
int n = 0;
|
||||
RRModePtr pMode;
|
||||
|
||||
for (pMode = pMonitor->pModes; pMode; pMode = pMode->next)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
typedef struct _RR10Data {
|
||||
RRScreenSizePtr sizes;
|
||||
int nsize;
|
||||
int nrefresh;
|
||||
int size;
|
||||
CARD16 refresh;
|
||||
} RR10DataRec, *RR10DataPtr;
|
||||
|
||||
static CARD16
|
||||
RRVerticalRefresh (xRRMonitorMode *mode)
|
||||
{
|
||||
CARD32 refresh;
|
||||
if (!mode->hTotal || !mode->vTotal)
|
||||
return 0;
|
||||
refresh = mode->dotClock / (mode->hTotal * mode->vTotal);
|
||||
if (refresh > 0xffff)
|
||||
refresh = 0xffff;
|
||||
return (CARD16) refresh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert 1.2 monitor data into 1.0 screen data
|
||||
*/
|
||||
static RR10DataPtr
|
||||
RR10GetData (ScreenPtr pScreen, RRMonitorPtr pMonitor)
|
||||
{
|
||||
RR10DataPtr data;
|
||||
RRScreenSizePtr size;
|
||||
int nmode = RRNumModes (pMonitor);
|
||||
int i;
|
||||
int j;
|
||||
RRRefreshPtr refresh;
|
||||
CARD16 vRefresh;
|
||||
RRModePtr pMode;
|
||||
|
||||
/* Make sure there is plenty of space for any combination */
|
||||
data = malloc (sizeof (RR10DataRec) +
|
||||
sizeof (RRScreenSizeRec) * nmode +
|
||||
sizeof (RRRefreshRec) * nmode);
|
||||
if (!data)
|
||||
return NULL;
|
||||
size = (RRScreenSizePtr) (data + 1);
|
||||
refresh = (RRRefreshPtr) (size + nmode);
|
||||
data->nsize = 0;
|
||||
data->nrefresh = 0;
|
||||
data->size = 0;
|
||||
data->refresh = 0;
|
||||
for (pMode = pMonitor->pModes; pMode; pMode = pMode->next)
|
||||
{
|
||||
for (i = 0; i < data->nsize; i++)
|
||||
if (pMode->mode.width == size[i].width &&
|
||||
pMode->mode.height == size[i].height)
|
||||
break;
|
||||
if (i == data->nsize)
|
||||
{
|
||||
size[i].width = pMode->mode.width;
|
||||
size[i].height = pMode->mode.height;
|
||||
size[i].mmWidth = pMode->mode.widthInMillimeters;
|
||||
size[i].mmHeight = pMode->mode.heightInMillimeters;
|
||||
size[i].nrefresh = 0;
|
||||
size[i].refresh = &refresh[data->nrefresh];
|
||||
data->nsize++;
|
||||
}
|
||||
vRefresh = RRVerticalRefresh (&pMode->mode);
|
||||
for (j = 0; j < size[i].nrefresh; j++)
|
||||
if (vRefresh == size[i].refresh[j].refresh)
|
||||
break;
|
||||
if (j == size[i].nrefresh)
|
||||
{
|
||||
size[i].refresh[j].refresh = vRefresh;
|
||||
size[i].refresh[j].pMode = pMode;
|
||||
size[i].nrefresh++;
|
||||
data->nrefresh++;
|
||||
}
|
||||
if (pMode == pMonitor->pMode)
|
||||
{
|
||||
data->size = i;
|
||||
data->refresh = vRefresh;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcRRGetScreenInfo (ClientPtr client)
|
||||
{
|
||||
|
@ -626,7 +778,11 @@ ProcRRGetScreenInfo (ClientPtr client)
|
|||
pScreen = pWin->drawable.pScreen;
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
rep.pad = 0;
|
||||
if (!pScrPriv)
|
||||
|
||||
if (pScrPriv)
|
||||
RRGetInfo (pScreen);
|
||||
|
||||
if (!pScrPriv && !pScrPriv->pMonitors)
|
||||
{
|
||||
rep.type = X_Reply;
|
||||
rep.setOfRotations = RR_Rotate_0;;
|
||||
|
@ -645,58 +801,49 @@ ProcRRGetScreenInfo (ClientPtr client)
|
|||
}
|
||||
else
|
||||
{
|
||||
RRMonitorPtr pMonitor = pScrPriv->pMonitors;
|
||||
int i, j;
|
||||
xScreenSizes *size;
|
||||
CARD16 *rates;
|
||||
CARD8 *data8;
|
||||
Bool has_rate = RRClientKnowsRates (client);
|
||||
RR10DataPtr pData;
|
||||
RRScreenSizePtr pSize;
|
||||
|
||||
RRGetInfo (pScreen);
|
||||
pData = RR10GetData (pScreen, pMonitor);
|
||||
if (!pData)
|
||||
return BadAlloc;
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.setOfRotations = pScrPriv->rotations;
|
||||
rep.setOfRotations = pMonitor->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 = pScrPriv->rotation;
|
||||
rep.nSizes = pScrPriv->nSizesInUse;
|
||||
rep.rate = pScrPriv->rate;
|
||||
rep.nrateEnts = 0;
|
||||
if (has_rate)
|
||||
{
|
||||
for (i = 0; i < pScrPriv->nSizes; i++)
|
||||
{
|
||||
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
|
||||
if (pSize->referenced)
|
||||
{
|
||||
rep.nrateEnts += (1 + pSize->nRatesInUse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pScrPriv->size >= 0)
|
||||
rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
|
||||
else
|
||||
return BadImplementation;
|
||||
rep.rotation = pMonitor->rotation;
|
||||
rep.nSizes = pData->nsize;
|
||||
rep.nrateEnts = pData->nrefresh;
|
||||
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 < pScrPriv->nSizes; i++)
|
||||
{
|
||||
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
|
||||
if (pSize->referenced)
|
||||
for (i = 0; i < pData->nsize; i++)
|
||||
{
|
||||
pSize = &pData->sizes[i];
|
||||
size->widthInPixels = pSize->width;
|
||||
size->heightInPixels = pSize->height;
|
||||
size->widthInMillimeters = pSize->mmWidth;
|
||||
|
@ -711,18 +858,15 @@ ProcRRGetScreenInfo (ClientPtr client)
|
|||
size++;
|
||||
if (has_rate)
|
||||
{
|
||||
*rates = pSize->nRatesInUse;
|
||||
*rates = pSize->nrefresh;
|
||||
if (client->swapped)
|
||||
{
|
||||
swaps (rates, n);
|
||||
}
|
||||
rates++;
|
||||
for (j = 0; j < pSize->nRates; j++)
|
||||
for (j = 0; j < pSize->nrefresh; j++)
|
||||
{
|
||||
RRScreenRatePtr pRate = &pSize->pRates[j];
|
||||
if (pRate->referenced)
|
||||
{
|
||||
*rates = pRate->rate;
|
||||
*rates = pSize->refresh[j].refresh;
|
||||
if (client->swapped)
|
||||
{
|
||||
swaps (rates, n);
|
||||
|
@ -731,8 +875,8 @@ ProcRRGetScreenInfo (ClientPtr client)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xfree (pData);
|
||||
|
||||
data8 = (CARD8 *) rates;
|
||||
|
||||
if (data8 - (CARD8 *) extra != extraLen)
|
||||
|
@ -770,12 +914,15 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
rrScrPrivPtr pScrPriv;
|
||||
TimeStamp configTime;
|
||||
TimeStamp time;
|
||||
RRScreenSizePtr pSize;
|
||||
int i;
|
||||
Rotation rotation;
|
||||
int rate;
|
||||
short oldWidth, oldHeight;
|
||||
Bool has_rate;
|
||||
RRMonitorPtr pMonitor;
|
||||
RRModePtr pMode;
|
||||
RR10DataPtr pData = NULL;
|
||||
RRScreenSizePtr pSize;
|
||||
|
||||
UpdateCurrentTime ();
|
||||
|
||||
|
@ -812,6 +959,14 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
if (!RRGetInfo (pScreen))
|
||||
return BadAlloc;
|
||||
|
||||
pMonitor = pScrPriv->pMonitors;
|
||||
if (!pMonitor)
|
||||
{
|
||||
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
|
||||
|
@ -823,26 +978,20 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
goto sendReply;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for the requested size
|
||||
*/
|
||||
pSize = 0;
|
||||
for (i = 0; i < pScrPriv->nSizes; i++)
|
||||
{
|
||||
pSize = &pScrPriv->pSizes[i];
|
||||
if (pSize->referenced && pSize->id == stuff->sizeID)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == pScrPriv->nSizes)
|
||||
pData = RR10GetData (pScreen, pMonitor);
|
||||
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
|
||||
|
@ -861,15 +1010,17 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
* Invalid rotation
|
||||
*/
|
||||
client->errorValue = stuff->rotation;
|
||||
xfree (pData);
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
if ((~pScrPriv->rotations) & rotation)
|
||||
if ((~pMonitor->rotations) & rotation)
|
||||
{
|
||||
/*
|
||||
* requested rotation or reflection not supported by screen
|
||||
*/
|
||||
client->errorValue = stuff->rotation;
|
||||
xfree (pData);
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
|
@ -883,21 +1034,24 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
|
||||
if (rate)
|
||||
{
|
||||
for (i = 0; i < pSize->nRates; i++)
|
||||
for (i = 0; i < pSize->nrefresh; i++)
|
||||
{
|
||||
RRScreenRatePtr pRate = &pSize->pRates[i];
|
||||
if (pRate->referenced && pRate->rate == rate)
|
||||
if (pSize->refresh[i].refresh == rate)
|
||||
break;
|
||||
}
|
||||
if (i == pSize->nRates)
|
||||
if (i == pSize->nrefresh)
|
||||
{
|
||||
/*
|
||||
* Invalid rate
|
||||
*/
|
||||
client->errorValue = rate;
|
||||
xfree (pData);
|
||||
return BadValue;
|
||||
}
|
||||
pMode = pSize->refresh[i].pMode;
|
||||
}
|
||||
else
|
||||
pMode = pSize->refresh[0].pMode;
|
||||
|
||||
/*
|
||||
* Make sure the requested set-time is not older than
|
||||
|
@ -912,9 +1066,51 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
/*
|
||||
* call out to ddx routine to effect the change
|
||||
*/
|
||||
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
|
||||
pSize))
|
||||
if (pScrPriv->rrSetScreenSize && pScrPriv->rrSetMode)
|
||||
{
|
||||
xScreenSizes oldSize;
|
||||
if (!(*pScrPriv->rrSetMode) (pScreen, 0, NULL, 0, 0, RR_Rotate_0))
|
||||
goto fail;
|
||||
oldSize.widthInPixels = pScreen->width;
|
||||
oldSize.heightInPixels = pScreen->width;
|
||||
oldSize.widthInMillimeters = pScreen->mmWidth;
|
||||
oldSize.heightInMillimeters = pScreen->mmHeight;
|
||||
if (!(*pScrPriv->rrSetScreenSize) (pScreen,
|
||||
pMode->mode.width,
|
||||
pMode->mode.height,
|
||||
pMode->mode.widthInMillimeters,
|
||||
pMode->mode.heightInMillimeters))
|
||||
{
|
||||
(void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode,
|
||||
pMonitor->x, pMonitor->y,
|
||||
pMonitor->rotation);
|
||||
goto fail;
|
||||
}
|
||||
if (!(*pScrPriv->rrSetMode) (pScreen, 0, pMode, 0, 0, rotation))
|
||||
{
|
||||
(void) (*pScrPriv->rrSetScreenSize) (pScreen,
|
||||
oldSize.widthInPixels,
|
||||
oldSize.heightInPixels,
|
||||
oldSize.widthInMillimeters,
|
||||
oldSize.heightInMillimeters);
|
||||
(void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode,
|
||||
pMonitor->x, pMonitor->y,
|
||||
pMonitor->rotation);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
#ifdef RANDR_SCREEN_INTERFACE
|
||||
else if (pScrPriv->rrSetConfig)
|
||||
{
|
||||
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, pSize))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
fail: ;
|
||||
/*
|
||||
* unknown DDX failure, report to client
|
||||
*/
|
||||
|
@ -925,7 +1121,7 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
/*
|
||||
* set current extension configuration pointers
|
||||
*/
|
||||
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
|
||||
RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation);
|
||||
|
||||
/*
|
||||
* Deliver ScreenChangeNotify events whenever
|
||||
|
@ -954,6 +1150,9 @@ ProcRRSetScreenConfig (ClientPtr client)
|
|||
|
||||
sendReply:
|
||||
|
||||
if (pData)
|
||||
xfree (pData);
|
||||
|
||||
rep.type = X_Reply;
|
||||
/* rep.status has already been filled in */
|
||||
rep.length = 0;
|
||||
|
@ -1055,7 +1254,7 @@ RRSetScreenConfig (ScreenPtr pScreen,
|
|||
/*
|
||||
* set current extension configuration pointers
|
||||
*/
|
||||
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
|
||||
RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation);
|
||||
|
||||
/*
|
||||
* Deliver ScreenChangeNotify events whenever
|
||||
|
@ -1075,7 +1274,6 @@ RRSetScreenConfig (ScreenPtr pScreen,
|
|||
* Fix pointer bounds and location
|
||||
*/
|
||||
ScreenRestructured (pScreen);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
@ -1286,21 +1484,113 @@ SProcRRDispatch (ClientPtr client)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static Bool
|
||||
RRScreenSizeMatches (RRScreenSizePtr a,
|
||||
RRScreenSizePtr b)
|
||||
/*
|
||||
* Register a monitor for a screen. identifier is a unique identifier
|
||||
* for the monitors of a particular screen.
|
||||
*/
|
||||
RRMonitorPtr
|
||||
RRRegisterMonitor (ScreenPtr pScreen,
|
||||
void *identifier,
|
||||
Rotation rotations)
|
||||
{
|
||||
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;
|
||||
rrScrPriv (pScreen);
|
||||
RRMonitorPtr pMonitor, *pPrev, *pInsert;
|
||||
|
||||
pInsert = NULL;
|
||||
for (pPrev = &pScrPriv->pMonitors; (pMonitor = *pPrev);
|
||||
pPrev = &(pMonitor)->next)
|
||||
{
|
||||
if (pMonitor->identifier == identifier)
|
||||
{
|
||||
pMonitor->referenced = TRUE;
|
||||
return pMonitor;
|
||||
}
|
||||
if (!pMonitor->referenced)
|
||||
pInsert = pPrev;
|
||||
}
|
||||
if (!pInsert)
|
||||
pInsert = pPrev;
|
||||
|
||||
/*
|
||||
* New monitor, add before the first unreferenced monitor
|
||||
*/
|
||||
pMonitor = xalloc (sizeof (RRMonitor));
|
||||
if (!pMonitor)
|
||||
return NULL;
|
||||
pMonitor->pScreen = pScreen;
|
||||
pMonitor->pModes = NULL;
|
||||
pMonitor->identifier = identifier;
|
||||
pMonitor->referenced = TRUE;
|
||||
pMonitor->oldReferenced = FALSE;
|
||||
pMonitor->rotations = RR_Rotate_0;
|
||||
|
||||
pMonitor->pMode = NULL;
|
||||
pMonitor->x = 0;
|
||||
pMonitor->y = 0;
|
||||
pMonitor->rotation = RR_Rotate_0;
|
||||
pMonitor->next = *pInsert;
|
||||
*pInsert = pMonitor;
|
||||
return pMonitor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a mode for a monitor
|
||||
*/
|
||||
|
||||
RRModePtr
|
||||
RRRegisterMode (RRMonitorPtr pMonitor,
|
||||
xRRMonitorMode *pModeline,
|
||||
char *name)
|
||||
{
|
||||
RRModePtr pMode, *pPrev, *pInsert = NULL;
|
||||
|
||||
/*
|
||||
* Find existing mode with same modeline and name
|
||||
*/
|
||||
for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next))
|
||||
{
|
||||
if (!memcmp (&pMode->mode, pModeline, sizeof (xRRMonitorMode)) &&
|
||||
pMode->mode.nameLength == pModeline->nameLength &&
|
||||
!memcmp (RRModeName(pMode), name, pModeline->nameLength))
|
||||
{
|
||||
pMode->referenced = TRUE;
|
||||
return pMode;
|
||||
}
|
||||
if (!pMode->referenced)
|
||||
pInsert = pPrev;
|
||||
}
|
||||
|
||||
if (!pInsert)
|
||||
pInsert = pPrev;
|
||||
|
||||
/*
|
||||
* Create a new mode, inserting before the first unreferenced mode
|
||||
*/
|
||||
pMode = xalloc (sizeof (RRMode) + pModeline->nameLength + 1);
|
||||
pMode->referenced = TRUE;
|
||||
pMode->oldReferenced = FALSE;
|
||||
pMode->mode = *pModeline;
|
||||
memcpy (RRModeName (pMode), name, pModeline->nameLength);
|
||||
RRModeName(pMode)[pModeline->nameLength] = '\0';
|
||||
pMode->next = *pInsert;
|
||||
*pInsert = pMode;
|
||||
return pMode;
|
||||
}
|
||||
|
||||
void
|
||||
RRSetCurrentMode (RRMonitorPtr pMonitor,
|
||||
RRModePtr pMode,
|
||||
int x,
|
||||
int y,
|
||||
Rotation rotation)
|
||||
{
|
||||
pMonitor->pMode = pMode;
|
||||
pMonitor->x = x;
|
||||
pMonitor->y = y;
|
||||
pMonitor->rotation = rotation;
|
||||
}
|
||||
|
||||
#ifdef RANDR_SCREEN_INTERFACE
|
||||
|
||||
RRScreenSizePtr
|
||||
RRRegisterSize (ScreenPtr pScreen,
|
||||
|
@ -1310,36 +1600,45 @@ RRRegisterSize (ScreenPtr pScreen,
|
|||
short mmHeight)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
int i;
|
||||
RRScreenSize tmp;
|
||||
RRScreenSizePtr pNew;
|
||||
xRRMonitorMode tmp;
|
||||
RRMonitorPtr pMonitor;
|
||||
RRModePtr pMode, *pPrev;
|
||||
char name[100];
|
||||
|
||||
if (!pScrPriv)
|
||||
return 0;
|
||||
return NULL;
|
||||
pMonitor = pScrPriv->pMonitors;
|
||||
if (!pMonitor)
|
||||
return NULL;
|
||||
|
||||
tmp.id = -1;
|
||||
for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next))
|
||||
if (pMode->mode.width == width &&
|
||||
pMode->mode.height == height &&
|
||||
pMode->mode.widthInMillimeters == mmWidth &&
|
||||
pMode->mode.heightInMillimeters == mmHeight)
|
||||
{
|
||||
pMode->referenced =TRUE;
|
||||
return (void *) pMode;
|
||||
}
|
||||
memset (&tmp, '\0', sizeof (xRRMonitorMode));
|
||||
memset (name, '\0', sizeof (name));
|
||||
sprintf (name, "%dx%d", width, height);
|
||||
tmp.width = width;
|
||||
tmp.height= height;
|
||||
tmp.mmWidth = mmWidth;
|
||||
tmp.mmHeight = mmHeight;
|
||||
tmp.pRates = 0;
|
||||
tmp.nRates = 0;
|
||||
tmp.nRatesInUse = 0;
|
||||
tmp.referenced = TRUE;
|
||||
tmp.oldReferenced = FALSE;
|
||||
for (i = 0; i < pScrPriv->nSizes; i++)
|
||||
if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
|
||||
{
|
||||
pScrPriv->pSizes[i].referenced = TRUE;
|
||||
return &pScrPriv->pSizes[i];
|
||||
tmp.widthInMillimeters = mmWidth;
|
||||
tmp.heightInMillimeters = mmHeight;
|
||||
tmp.nameLength = strlen (name) + 10; /* leave space for refresh */
|
||||
pMode = RRRegisterMode (pMonitor, &tmp, name);
|
||||
return (void *) pMode;
|
||||
}
|
||||
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];
|
||||
|
||||
static Bool
|
||||
RRModesMatchSize (RRModePtr a, RRModePtr b)
|
||||
{
|
||||
return (a->mode.width == a->mode.width &&
|
||||
a->mode.height == b->mode.height &&
|
||||
a->mode.widthInMillimeters == b->mode.widthInMillimeters &&
|
||||
a->mode.heightInMillimeters == b->mode.heightInMillimeters);
|
||||
}
|
||||
|
||||
Bool RRRegisterRate (ScreenPtr pScreen,
|
||||
|
@ -1347,31 +1646,61 @@ Bool RRRegisterRate (ScreenPtr pScreen,
|
|||
int rate)
|
||||
{
|
||||
rrScrPriv(pScreen);
|
||||
int i;
|
||||
RRScreenRatePtr pNew, pRate;
|
||||
RRMonitorPtr pMonitor;
|
||||
RRModePtr pSizeMode = (RRModePtr) pSize;
|
||||
RRModePtr pMode, *pPrev;
|
||||
CARD16 width = pSizeMode->mode.width;
|
||||
CARD16 height = pSizeMode->mode.height;
|
||||
char name[100];
|
||||
xRRMonitorMode modeLine;
|
||||
|
||||
if (!pScrPriv)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < pSize->nRates; i++)
|
||||
pMonitor = pScrPriv->pMonitors;
|
||||
if (!pMonitor)
|
||||
return FALSE;
|
||||
|
||||
for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &pMode->next)
|
||||
{
|
||||
pRate = &pSize->pRates[i];
|
||||
if (pRate->rate == rate)
|
||||
if (RRModesMatchSize (pMode, pSizeMode))
|
||||
{
|
||||
pRate->referenced = TRUE;
|
||||
if (pMode->mode.dotClock == 0)
|
||||
{
|
||||
/*
|
||||
* First refresh for this size; reprogram this mode
|
||||
* with the right refresh.
|
||||
*/
|
||||
pMode->mode.hSyncStart = width;
|
||||
pMode->mode.hSyncEnd = width;
|
||||
pMode->mode.hTotal = width;
|
||||
pMode->mode.hSkew = 0;
|
||||
pMode->mode.vSyncStart = height;
|
||||
pMode->mode.vSyncEnd = height;
|
||||
pMode->mode.vTotal = height;
|
||||
pMode->mode.dotClock = width * height * rate;
|
||||
sprintf ((char *) (pMode + 1), "%dx%d@%d", width, height, rate);
|
||||
pMode->mode.modeFlags = 0;
|
||||
pMode->mode.nameLength = strlen ((char *) (pMode + 1));
|
||||
pMode->referenced = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else if (rate == RRVerticalRefresh (&pMode->mode))
|
||||
{
|
||||
pMode->referenced = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pNew = xrealloc (pSize->pRates,
|
||||
(pSize->nRates + 1) * sizeof (RRScreenRate));
|
||||
if (!pNew)
|
||||
sprintf (name, "%dx%d@%d", pSizeMode->mode.width, pSizeMode->mode.height,
|
||||
rate);
|
||||
modeLine = pSizeMode->mode;
|
||||
modeLine.dotClock = rate * modeLine.vTotal * modeLine.hTotal;
|
||||
modeLine.nameLength = strlen (name);
|
||||
pMode = RRRegisterMode (pMonitor, &modeLine, name);
|
||||
if (!pMode)
|
||||
return FALSE;
|
||||
pRate = &pNew[pSize->nRates++];
|
||||
pRate->rate = rate;
|
||||
pRate->referenced = TRUE;
|
||||
pRate->oldReferenced = FALSE;
|
||||
pSize->pRates = pNew;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1379,11 +1708,15 @@ Rotation
|
|||
RRGetRotation(ScreenPtr pScreen)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
RRMonitorPtr pMonitor;
|
||||
|
||||
if (!pScrPriv)
|
||||
return RR_Rotate_0;
|
||||
|
||||
return pScrPriv->rotation;
|
||||
pMonitor = pScrPriv->pMonitors;
|
||||
if (!pMonitor)
|
||||
return RR_Rotate_0;
|
||||
return pMonitor->rotation;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1393,11 +1726,25 @@ RRSetCurrentConfig (ScreenPtr pScreen,
|
|||
RRScreenSizePtr pSize)
|
||||
{
|
||||
rrScrPriv (pScreen);
|
||||
RRMonitorPtr pMonitor;
|
||||
RRModePtr pMode;
|
||||
RRModePtr pSizeMode = (RRModePtr) pSize;
|
||||
|
||||
if (!pScrPriv)
|
||||
return;
|
||||
pMonitor = pScrPriv->pMonitors;
|
||||
if (!pMonitor)
|
||||
return;
|
||||
|
||||
pScrPriv->rotation = rotation;
|
||||
pScrPriv->size = pSize - pScrPriv->pSizes;
|
||||
pScrPriv->rate = rate;
|
||||
for (pMode = pMonitor->pModes; pMode; pMode = pMode->next)
|
||||
{
|
||||
if (RRModesMatchSize (pMode, pSizeMode) &&
|
||||
RRVerticalRefresh (&pMode->mode) == rate)
|
||||
break;
|
||||
}
|
||||
if (!pMode)
|
||||
return;
|
||||
|
||||
RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,11 +34,19 @@
|
|||
|
||||
#include <X11/extensions/randrproto.h>
|
||||
|
||||
#define RANDR_SCREEN_INTERFACE 1
|
||||
|
||||
/*
|
||||
* Modeline for a monitor. Name follows directly after this struct
|
||||
*/
|
||||
|
||||
#define RRModeName(pMode) ((char *) (pMode + 1))
|
||||
|
||||
typedef struct _rrMode {
|
||||
struct _rrMode *next;
|
||||
int id;
|
||||
Bool referenced;
|
||||
Bool oldReferenced;
|
||||
int id;
|
||||
xRRMonitorMode mode;
|
||||
} RRMode, *RRModePtr;
|
||||
|
||||
|
@ -47,12 +55,15 @@ typedef struct _rrMonitor {
|
|||
ScreenPtr pScreen;
|
||||
RRModePtr pModes;
|
||||
void *identifier; /* made unique by DDX */
|
||||
int id; /* index in list of monitors */
|
||||
Bool referenced;
|
||||
Bool oldReferenced;
|
||||
Rotation rotations;
|
||||
|
||||
/*
|
||||
* Current state
|
||||
*/
|
||||
int mode;
|
||||
RRModePtr pMode;
|
||||
int x, y;
|
||||
Rotation rotation;
|
||||
} RRMonitor, *RRMonitorPtr;
|
||||
|
@ -76,7 +87,18 @@ typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen);
|
|||
|
||||
#ifdef RANDR_SCREEN_INTERFACE
|
||||
|
||||
typedef void *RRScreenSizePtr;
|
||||
typedef struct _rrRefresh {
|
||||
CARD16 refresh;
|
||||
RRModePtr pMode;
|
||||
} RRRefreshRec, *RRRefreshPtr;
|
||||
|
||||
typedef struct _rrScreenSize {
|
||||
int id;
|
||||
short width, height;
|
||||
short mmWidth, mmHeight;
|
||||
int nrefresh;
|
||||
RRRefreshPtr refresh;
|
||||
} RRScreenSizeRec, *RRScreenSizePtr;
|
||||
|
||||
typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
|
||||
Rotation rotation,
|
||||
|
@ -87,12 +109,23 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
|
|||
|
||||
|
||||
typedef struct _rrScrPriv {
|
||||
RRSetModeProcPtr rrSetMode;
|
||||
/*
|
||||
* 'public' part of the structure; DDXen fill this in
|
||||
* as they initialize
|
||||
*/
|
||||
#ifdef RANDR_SCREEN_INTERFACE
|
||||
RRSetConfigProcPtr rrSetConfig;
|
||||
#endif
|
||||
RRGetInfoProcPtr rrGetInfo;
|
||||
RRCloseScreenProcPtr CloseScreen;
|
||||
RRSetScreenSizeProcPtr rrSetScreenSize;
|
||||
RRSetModeProcPtr rrSetMode;
|
||||
|
||||
/*
|
||||
* Private part of the structure; not considered part of the ABI
|
||||
*/
|
||||
TimeStamp lastSetTime; /* last changed by client */
|
||||
TimeStamp lastConfigTime; /* possible configs changed */
|
||||
RRCloseScreenProcPtr CloseScreen;
|
||||
|
||||
/*
|
||||
* monitor data
|
||||
|
@ -105,7 +138,6 @@ typedef struct _rrScrPriv {
|
|||
*/
|
||||
Rotation rotations;
|
||||
|
||||
RRSetConfigProcPtr rrSetConfig;
|
||||
|
||||
Rotation rotation;
|
||||
#endif
|
||||
|
@ -137,8 +169,7 @@ RRRegisterMonitor (ScreenPtr pScreen,
|
|||
RRModePtr
|
||||
RRRegisterMode (RRMonitorPtr pMonitor,
|
||||
xRRMonitorMode *pMode,
|
||||
char *name,
|
||||
int nameLength);
|
||||
char *name);
|
||||
|
||||
/*
|
||||
* Finally, set the current configuration of each monitor
|
||||
|
@ -147,6 +178,8 @@ RRRegisterMode (RRMonitorPtr pMonitor,
|
|||
void
|
||||
RRSetCurrentMode (RRMonitorPtr pMonitor,
|
||||
RRModePtr pMode,
|
||||
int x,
|
||||
int y,
|
||||
Rotation rotation);
|
||||
|
||||
Bool RRScreenInit(ScreenPtr pScreen);
|
||||
|
@ -167,6 +200,8 @@ Bool
|
|||
miRRSetMode (ScreenPtr pScreen,
|
||||
int monitor,
|
||||
RRModePtr pMode,
|
||||
int x,
|
||||
int y,
|
||||
Rotation rotation);
|
||||
|
||||
#ifdef RANDR_SCREEN_INTERFACE
|
||||
|
|
Loading…
Reference in New Issue