summaryrefslogtreecommitdiff
path: root/randr/randr.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@neko.keithp.com>2006-07-17 14:43:07 -0400
committerKeith Packard <keithp@neko.keithp.com>2006-09-17 23:08:11 -0700
commit8dec74321d916f204f8182f1b93a65defbe50e78 (patch)
tree3049ea8b5dfcc6677507e36bbc6c7323333cf932 /randr/randr.c
parentcab3a0145f2483fe43b5db5f5dd2076db9757fe5 (diff)
Successful legacy RandR API/Protocol emulation for query.
These changes clean up minor errors to make it possible to list the available modes for a monitor using legacy APIs in both the X server DDX and RandR protocol. Setting modes is untested, so it probably doesn't work.
Diffstat (limited to 'randr/randr.c')
-rw-r--r--randr/randr.c331
1 files changed, 178 insertions, 153 deletions
diff --git a/randr/randr.c b/randr/randr.c
index 4a5cd4e1d..58d8f177f 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -542,6 +542,7 @@ RRGetInfo (ScreenPtr pScreen)
pMode->id = modeid++;
if (!pMode->oldReferenced)
changed = TRUE;
+ pPrevMode = &pMode->next;
}
else
{
@@ -550,6 +551,7 @@ RRGetInfo (ScreenPtr pScreen)
RRFreeMode (pMode);
}
}
+ pPrevMon = &pMonitor->next;
}
else
{
@@ -716,6 +718,7 @@ RR10GetData (ScreenPtr pScreen, RRMonitorPtr pMonitor)
return NULL;
size = (RRScreenSizePtr) (data + 1);
refresh = (RRRefreshPtr) (size + nmode);
+ data->sizes = size;
data->nsize = 0;
data->nrefresh = 0;
data->size = 0;
@@ -728,6 +731,7 @@ RR10GetData (ScreenPtr pScreen, RRMonitorPtr pMonitor)
break;
if (i == data->nsize)
{
+ size[i].id = i;
size[i].width = pMode->mode.width;
size[i].height = pMode->mode.height;
size[i].mmWidth = pMode->mode.widthInMillimeters;
@@ -823,7 +827,7 @@ ProcRRGetScreenInfo (ClientPtr client)
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.rotation = pMonitor->rotation;
rep.nSizes = pData->nsize;
- rep.nrateEnts = pData->nrefresh;
+ rep.nrateEnts = pData->nrefresh + pData->nsize;
rep.sizeID = pData->size;
rep.rate = pData->refresh;
@@ -904,6 +908,97 @@ ProcRRGetScreenInfo (ClientPtr client)
}
static int
+RRMonitorSetMode (ScreenPtr pScreen, RRMonitorPtr pMonitor,
+ RRModePtr pMode, int x, int y, Rotation rotation,
+ TimeStamp time)
+{
+ rrScrPriv(pScreen);
+ short oldWidth, oldHeight;
+
+ oldWidth = pScreen->width;
+ oldHeight = pScreen->height;
+
+ /*
+ * call out to ddx routine to effect the change
+ */
+ if (pScrPriv->rrSetScreenSize && pScrPriv->rrSetMode)
+ {
+ xScreenSizes oldSize;
+ if (!(*pScrPriv->rrSetMode) (pScreen, 0, NULL, 0, 0, RR_Rotate_0))
+ return RRSetConfigFailed;
+ 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);
+ return RRSetConfigFailed;
+ }
+ 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);
+ return RRSetConfigFailed;
+ }
+ }
+#ifdef RANDR_SCREEN_INTERFACE
+ else if (pScrPriv->rrSetConfig)
+ {
+ int rate = RRVerticalRefresh (&pMode->mode);
+ RRScreenSizeRec size;
+
+ size.width = pMode->mode.width;
+ size.height = pMode->mode.height;
+ size.mmWidth = pMode->mode.widthInMillimeters;
+ size.mmHeight = pMode->mode.heightInMillimeters;
+ if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, &size))
+ return RRSetConfigFailed;
+ }
+#endif
+ else
+ return RRSetConfigFailed;
+
+ /*
+ * set current extension configuration pointers
+ */
+ RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation);
+
+ /*
+ * Deliver ScreenChangeNotify events whenever
+ * the configuration is updated
+ */
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+ RRSendConfigNotify (pScreen);
+ RREditConnectionInfo (pScreen);
+
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured (pScreen);
+ pScrPriv->lastSetTime = time;
+ return RRSetConfigSuccess;
+}
+
+static int
ProcRRSetScreenConfig (ClientPtr client)
{
REQUEST(xRRSetScreenConfigReq);
@@ -917,7 +1012,6 @@ ProcRRSetScreenConfig (ClientPtr client)
int i;
Rotation rotation;
int rate;
- short oldWidth, oldHeight;
Bool has_rate;
RRMonitorPtr pMonitor;
RRModePtr pMode;
@@ -947,9 +1041,6 @@ ProcRRSetScreenConfig (ClientPtr client)
time = ClientTimeToServerTime(stuff->timestamp);
configTime = ClientTimeToServerTime(stuff->configTimestamp);
- oldWidth = pScreen->width;
- oldHeight = pScreen->height;
-
if (!pScrPriv)
{
time = currentTime;
@@ -1063,90 +1154,7 @@ ProcRRSetScreenConfig (ClientPtr client)
goto sendReply;
}
- /*
- * call out to ddx routine to effect the change
- */
- 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
- */
- rep.status = RRSetConfigFailed;
- goto sendReply;
- }
-
- /*
- * set current extension configuration pointers
- */
- RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation);
-
- /*
- * Deliver ScreenChangeNotify events whenever
- * the configuration is updated
- */
- WalkTree (pScreen, TellChanged, (pointer) pScreen);
-
- /*
- * Deliver ConfigureNotify events when root changes
- * pixel size
- */
- if (oldWidth != pScreen->width || oldHeight != pScreen->height)
- RRSendConfigNotify (pScreen);
- RREditConnectionInfo (pScreen);
-
- /*
- * Fix pointer bounds and location
- */
- ScreenRestructured (pScreen);
- pScrPriv->lastSetTime = time;
-
- /*
- * Report Success
- */
- rep.status = RRSetConfigSuccess;
+ rep.status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0, rotation, time);
sendReply:
@@ -1182,11 +1190,20 @@ RRSetScreenConfig (ScreenPtr pScreen,
RRScreenSizePtr pSize)
{
rrScrPrivPtr pScrPriv;
- int i;
+ 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;
@@ -1219,61 +1236,24 @@ RRSetScreenConfig (ScreenPtr pScreen,
return BadMatch;
}
- /*
- * Validate requested refresh
- */
- if (rate)
+ for (pMode = pMonitor->pModes; pMode; pMode = pMode->next)
{
- for (i = 0; i < pSize->nRates; i++)
- {
- RRScreenRatePtr pRate = &pSize->pRates[i];
- if (pRate->referenced && pRate->rate == rate)
- break;
- }
- if (i == pSize->nRates)
+ 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))
{
- /*
- * Invalid rate
- */
- return BadValue;
+ break;
}
}
-
- /*
- * call out to ddx routine to effect the change
- */
- if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
- pSize))
- {
- /*
- * unknown DDX failure, report to client
- */
- return BadImplementation;
- }
-
- /*
- * set current extension configuration pointers
- */
- RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation);
-
- /*
- * Deliver ScreenChangeNotify events whenever
- * the configuration is updated
- */
- WalkTree (pScreen, TellChanged, (pointer) pScreen);
-
- /*
- * Deliver ConfigureNotify events when root changes
- * pixel size
- */
- if (oldWidth != pScreen->width || oldHeight != pScreen->height)
- RRSendConfigNotify (pScreen);
- RREditConnectionInfo (pScreen);
+ if (!pMode)
+ return BadValue;
- /*
- * Fix pointer bounds and location
- */
- ScreenRestructured (pScreen);
+ status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0,
+ rotation, currentTime);
+ if (status != RRSetConfigSuccess)
+ return BadImplementation;
return Success;
}
@@ -1387,23 +1367,63 @@ ProcRRSelectInput (ClientPtr client)
}
+static int ProcRRGetScreenSizeRange (ClientPtr pClient)
+{
+ return BadImplementation;
+}
+
+static int ProcRRSetScreenSize (ClientPtr pClient)
+{
+ return BadImplementation;
+}
+
+static int ProcRRGetMonitorInfo (ClientPtr pClient)
+{
+ return BadImplementation;
+}
+
+static int ProcRRAddMonitorMode (ClientPtr pClient)
+{
+ return BadImplementation;
+}
+
+static int ProcRRDeleteMonitorMode (ClientPtr pClient)
+{
+ return BadImplementation;
+}
+
+static int ProcRRSetMonitorConfig (ClientPtr pClient)
+{
+ return BadImplementation;
+}
+
+int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
+ ProcRRQueryVersion, /* 0 */
+/* we skip 1 to make old clients fail pretty immediately */
+ NULL, /* 1 ProcRandrOldGetScreenInfo */
+/* V1.0 apps share the same set screen config request id */
+ ProcRRSetScreenConfig, /* 2 */
+ NULL, /* 3 ProcRandrOldScreenChangeSelectInput */
+/* 3 used to be ScreenChangeSelectInput; deprecated */
+ ProcRRSelectInput, /* 4 */
+ ProcRRGetScreenInfo, /* 5 */
+/* V1.2 additions */
+ ProcRRGetScreenSizeRange, /* 6 */
+ ProcRRSetScreenSize, /* 7 */
+ ProcRRGetMonitorInfo, /* 8 */
+ ProcRRAddMonitorMode, /* 9 */
+ ProcRRDeleteMonitorMode, /* 10 */
+ ProcRRSetMonitorConfig, /* 11 */
+};
+
+
static int
ProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
- switch (stuff->data)
- {
- case X_RRQueryVersion:
- return ProcRRQueryVersion(client);
- case X_RRSetScreenConfig:
- return ProcRRSetScreenConfig(client);
- case X_RRSelectInput:
- return ProcRRSelectInput(client);
- case X_RRGetScreenInfo:
- return ProcRRGetScreenInfo(client);
- default:
+ if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
return BadRequest;
- }
+ return (*ProcRandrVector[stuff->data]) (client);
}
static int
@@ -1609,7 +1629,12 @@ RRRegisterSize (ScreenPtr pScreen,
return NULL;
pMonitor = pScrPriv->pMonitors;
if (!pMonitor)
- return NULL;
+ {
+ pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0);
+ if (!pMonitor)
+ return NULL;
+ }
+ pMonitor->referenced = TRUE;
for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next))
if (pMode->mode.width == width &&