summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xfree86/common/Makefile.am2
-rw-r--r--randr/mirandr.c13
-rw-r--r--randr/randr.c4
-rw-r--r--randr/randrstr.h36
-rw-r--r--randr/rrcrtc.c170
-rw-r--r--randr/rrinfo.c14
-rw-r--r--randr/rrmode.c108
-rw-r--r--randr/rroutput.c44
-rw-r--r--randr/rrscreen.c32
9 files changed, 254 insertions, 169 deletions
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index 0e1582e69..35b22f007 100644
--- a/hw/xfree86/common/Makefile.am
+++ b/hw/xfree86/common/Makefile.am
@@ -51,7 +51,7 @@ sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \
xf86PciInfo.h xf86Priv.h xf86Privstr.h xf86Resources.h \
xf86cmap.h xf86fbman.h xf86str.h $(XISDKINCS) \
$(XVSDKINCS) atKeynames.h xf86Version.h xorgVersion.h \
- xf86sbusBus.h xf86xv.h xf86xvmc.h xf86xvpriv.h
+ xf86sbusBus.h xf86xv.h xf86xvmc.h xf86xvpriv.h xf86Keymap.h
DISTCLEANFILES = xf86Build.h
CLEANFILES = $(BUILT_SOURCES)
diff --git a/randr/mirandr.c b/randr/mirandr.c
index 11c299133..3f56fe42e 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -113,17 +113,24 @@ miRandRInit (ScreenPtr pScreen)
modeInfo.height = pScreen->height;
modeInfo.nameLength = strlen (name);
- mode = RRModeGet (pScreen, &modeInfo, name);
+ mode = RRModeGet (&modeInfo, name);
if (!mode)
return FALSE;
- crtc = RRCrtcCreate (pScreen, NULL);
+ crtc = RRCrtcCreate (NULL);
if (!crtc)
return FALSE;
+ if (!RRCrtcAttachScreen (crtc, pScreen))
+ {
+ RRCrtcDestroy (crtc);
+ return FALSE;
+ }
- output = RROutputCreate (pScreen, "screen", 6, NULL);
+ output = RROutputCreate ("screen", 6, NULL);
if (!output)
return FALSE;
+ if (!RROutputAttachScreen (output, pScreen))
+ return FALSE;
if (!RROutputSetClones (output, NULL, 0))
return FALSE;
if (!RROutputSetModes (output, &mode, 1, 0))
diff --git a/randr/randr.c b/randr/randr.c
index 7b39e8045..4426c4773 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -103,8 +103,6 @@ RRCloseScreen (int i, ScreenPtr pScreen)
RRCrtcDestroy (pScrPriv->crtcs[j]);
for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
RROutputDestroy (pScrPriv->outputs[j]);
- for (j = pScrPriv->numModes - 1; j >= 0; j--)
- RRModeDestroy (pScrPriv->modes[j]);
xfree (pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
@@ -257,8 +255,6 @@ Bool RRScreenInit(ScreenPtr pScreen)
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
- pScrPriv->numModes = 0;
- pScrPriv->modes = NULL;
pScrPriv->numOutputs = 0;
pScrPriv->outputs = NULL;
pScrPriv->numCrtcs = 0;
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 60877a3c1..345418b8f 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -79,7 +79,6 @@ struct _rrMode {
xRRModeInfo mode;
char *name;
void *devPrivate;
- ScreenPtr screen;
Bool userDefined;
};
@@ -210,10 +209,6 @@ typedef struct _rrScrPriv {
CARD16 width, height; /* last known screen size */
Bool layoutChanged; /* screen layout changed */
- /* modes, outputs and crtcs */
- int numModes;
- RRModePtr *modes;
-
int numOutputs;
RROutputPtr *outputs;
@@ -457,10 +452,17 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
* Create a CRTC
*/
RRCrtcPtr
-RRCrtcCreate (ScreenPtr pScreen,
- void *devPrivate);
+RRCrtcCreate (void *devPrivate);
/*
+ * Attach a CRTC to a screen. Once done, this cannot be
+ * undone without destroying the CRTC; it is separate from Create
+ * only to allow an xf86-based driver to create objects in preinit
+ */
+Bool
+RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen);
+
+/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
*/
@@ -556,8 +558,7 @@ RRClientKnowsRates (ClientPtr pClient);
*/
RRModePtr
-RRModeGet (ScreenPtr pScreen,
- xRRModeInfo *modeInfo,
+RRModeGet (xRRModeInfo *modeInfo,
const char *name);
void
@@ -571,6 +572,12 @@ void
RRModeDestroy (RRModePtr mode);
/*
+ * Return a list of modes that are valid for some output in pScreen
+ */
+RRModePtr *
+RRModesForScreen (ScreenPtr pScreen, int *num_ret);
+
+/*
* Initialize mode type
*/
Bool
@@ -601,12 +608,19 @@ RROutputChanged (RROutputPtr output);
*/
RROutputPtr
-RROutputCreate (ScreenPtr pScreen,
- const char *name,
+RROutputCreate (const char *name,
int nameLength,
void *devPrivate);
/*
+ * Attach an output to a screen, again split from creation so
+ * xf86 DDXen can create randr resources before the ScreenRec
+ * exists
+ */
+Bool
+RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen);
+
+/*
* Notify extension that output parameters have been changed
*/
Bool
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 76d0b6bf5..9f7177a34 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -32,43 +32,34 @@ void
RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
{
ScreenPtr pScreen = crtc->pScreen;
- rrScrPriv(pScreen);
crtc->changed = TRUE;
- pScrPriv->changed = TRUE;
- /*
- * Send ConfigureNotify on any layout change
- */
- if (layoutChanged)
- pScrPriv->layoutChanged = TRUE;
+ if (pScreen)
+ {
+ rrScrPriv(pScreen);
+
+ pScrPriv->changed = TRUE;
+ /*
+ * Send ConfigureNotify on any layout change
+ */
+ if (layoutChanged)
+ pScrPriv->layoutChanged = TRUE;
+ }
}
/*
* Create a CRTC
*/
RRCrtcPtr
-RRCrtcCreate (ScreenPtr pScreen,
- void *devPrivate)
+RRCrtcCreate (void *devPrivate)
{
- rrScrPriv (pScreen);
RRCrtcPtr crtc;
- RRCrtcPtr *crtcs;
crtc = xalloc (sizeof (RRCrtcRec));
if (!crtc)
return NULL;
- if (pScrPriv->numCrtcs)
- crtcs = xrealloc (pScrPriv->crtcs,
- (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
- else
- crtcs = xalloc (sizeof (RRCrtcPtr));
- if (!crtcs)
- {
- xfree (crtc);
- return NULL;
- }
crtc->id = FakeClientID (0);
- crtc->pScreen = pScreen;
+ crtc->pScreen = NULL;
crtc->mode = NULL;
crtc->x = 0;
crtc->y = 0;
@@ -84,11 +75,37 @@ RRCrtcCreate (ScreenPtr pScreen,
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
return NULL;
+ return crtc;
+}
+
+/*
+ * Attach a Crtc to a screen. This is done as a separate step
+ * so that an xf86-based driver can create CRTCs in PreInit
+ * before the Screen has been created
+ */
+
+Bool
+RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen)
+{
+ rrScrPriv (pScreen);
+ RRCrtcPtr *crtcs;
+
+ /* make space for the crtc pointer */
+ if (pScrPriv->numCrtcs)
+ crtcs = xrealloc (pScrPriv->crtcs,
+ (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
+ else
+ crtcs = xalloc (sizeof (RRCrtcPtr));
+ if (!crtcs)
+ return FALSE;
+
+ /* attach the screen and crtc together */
+ crtc->pScreen = pScreen;
pScrPriv->crtcs = crtcs;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
RRCrtcChanged (crtc, TRUE);
- return crtc;
+ return TRUE;
}
/*
@@ -243,7 +260,6 @@ RRCrtcSet (RRCrtcPtr crtc,
RROutputConfigPtr outputs)
{
ScreenPtr pScreen = crtc->pScreen;
- rrScrPriv(pScreen);
/* See if nothing changed */
if (crtc->mode == mode &&
@@ -255,45 +271,49 @@ RRCrtcSet (RRCrtcPtr crtc,
{
return TRUE;
}
-#if RANDR_12_INTERFACE
- if (pScrPriv->rrCrtcSet)
- {
- return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
- rotation, numOutputs, outputs);
- }
-#endif
-#if RANDR_10_INTERFACE
- if (pScrPriv->rrSetConfig)
+ if (pScreen)
{
- RRScreenSize size;
- RRScreenRate rate;
- Bool ret;
-
- size.width = mode->mode.width;
- size.height = mode->mode.height;
- if (outputs[0].output->mmWidth && outputs[0].output->mmHeight)
+#if RANDR_12_INTERFACE
+ rrScrPriv(pScreen);
+ if (pScrPriv->rrCrtcSet)
{
- size.mmWidth = outputs[0].output->mmWidth;
- size.mmHeight = outputs[0].output->mmHeight;
+ return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
+ rotation, numOutputs, outputs);
}
- else
+#endif
+#if RANDR_10_INTERFACE
+ if (pScrPriv->rrSetConfig)
{
- size.mmWidth = pScreen->mmWidth;
- size.mmHeight = pScreen->mmHeight;
+ RRScreenSize size;
+ RRScreenRate rate;
+ Bool ret;
+
+ size.width = mode->mode.width;
+ size.height = mode->mode.height;
+ if (outputs[0].output->mmWidth && outputs[0].output->mmHeight)
+ {
+ size.mmWidth = outputs[0].output->mmWidth;
+ size.mmHeight = outputs[0].output->mmHeight;
+ }
+ else
+ {
+ size.mmWidth = pScreen->mmWidth;
+ size.mmHeight = pScreen->mmHeight;
+ }
+ size.nRates = 1;
+ rate.rate = RRVerticalRefresh (&mode->mode);
+ size.pRates = &rate;
+ ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
+ /*
+ * Old 1.0 interface tied screen size to mode size
+ */
+ if (ret)
+ RRCrtcNotify (crtc, mode, x, y, rotation, 1, &outputs[0].output);
+ return ret;
}
- size.nRates = 1;
- rate.rate = RRVerticalRefresh (&mode->mode);
- size.pRates = &rate;
- ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
- /*
- * Old 1.0 interface tied screen size to mode size
- */
- if (ret)
- RRCrtcNotify (crtc, mode, x, y, rotation, 1, &outputs[0].output);
- return ret;
- }
#endif
- RRTellChanged (pScreen);
+ RRTellChanged (pScreen);
+ }
return FALSE;
}
@@ -311,22 +331,26 @@ RRCrtcDestroyResource (pointer value, XID pid)
{
RRCrtcPtr crtc = (RRCrtcPtr) value;
ScreenPtr pScreen = crtc->pScreen;
- rrScrPriv(pScreen);
- int i;
- for (i = 0; i < pScrPriv->numCrtcs; i++)
+ if (pScreen)
{
- if (pScrPriv->crtcs[i] == crtc)
+ rrScrPriv(pScreen);
+ int i;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++)
{
- memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
- (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr));
- --pScrPriv->numCrtcs;
- break;
+ if (pScrPriv->crtcs[i] == crtc)
+ {
+ memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
+ (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr));
+ --pScrPriv->numCrtcs;
+ break;
+ }
}
}
if (crtc->gammaRed)
xfree (crtc->gammaRed);
- xfree (value);
+ xfree (crtc);
return 1;
}
@@ -343,15 +367,18 @@ RRCrtcGammaSet (RRCrtcPtr crtc,
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);
+ if (pScreen)
+ {
+ rrScrPriv(pScreen);
+ if (pScrPriv->rrCrtcSetGamma)
+ ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
+ }
#endif
return ret;
}
@@ -433,6 +460,9 @@ ProcRRGetCrtcInfo (ClientPtr client)
if (!crtc)
return RRErrorBase + BadRRCrtc;
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
pScreen = crtc->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
@@ -589,7 +619,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
for (j = 0; j < outputs[i].output->numCrtcs; j++)
if (outputs[i].output->crtcs[j] == crtc)
break;
- if (j == outputs[j].output->numCrtcs)
+ if (j == outputs[i].output->numCrtcs)
{
if (outputs)
xfree (outputs);
diff --git a/randr/rrinfo.c b/randr/rrinfo.c
index e92caadfa..244b089f3 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -44,7 +44,7 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height *
(CARD32) refresh);
modeInfo.nameLength = strlen (name);
- mode = RRModeGet (pScreen, &modeInfo, name);
+ mode = RRModeGet (&modeInfo, name);
if (!mode)
return NULL;
for (i = 0; i < output->numModes; i++)
@@ -90,12 +90,19 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
if (pScrPriv->numOutputs == 0 &&
pScrPriv->numCrtcs == 0)
{
- crtc = RRCrtcCreate (pScreen, NULL);
+ crtc = RRCrtcCreate (NULL);
if (!crtc)
return;
- output = RROutputCreate (pScreen, "default", 7, NULL);
+ if (!RRCrtcAttachScreen (crtc, pScreen))
+ {
+ RRCrtcDestroy (crtc);
+ return;
+ }
+ output = RROutputCreate ("default", 7, NULL);
if (!output)
return;
+ if (!RROutputAttachScreen (output, pScreen))
+ return;
RROutputSetCrtcs (output, &crtc, 1);
RROutputSetCrtc (output, crtc);
RROutputSetConnection (output, RR_Connected);
@@ -206,7 +213,6 @@ RRGetInfo (ScreenPtr pScreen)
if (pScrPriv->nSizes)
RRScanOldConfig (pScreen, rotations);
#endif
- RRModePruneUnused (pScreen);
RRTellChanged (pScreen);
return TRUE;
}
diff --git a/randr/rrmode.c b/randr/rrmode.c
index fb4b5eb1e..3cd9ef273 100644
--- a/randr/rrmode.c
+++ b/randr/rrmode.c
@@ -42,19 +42,23 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *b)
return TRUE;
}
+/*
+ * Keep a list so it's easy to find modes in the resource database.
+ */
+static int num_modes;
+static RRModePtr *modes;
+
RRModePtr
-RRModeGet (ScreenPtr pScreen,
- xRRModeInfo *modeInfo,
+RRModeGet (xRRModeInfo *modeInfo,
const char *name)
{
- rrScrPriv (pScreen);
int i;
RRModePtr mode;
- RRModePtr *modes;
+ RRModePtr *newModes;
- for (i = 0; i < pScrPriv->numModes; i++)
+ for (i = 0; i < num_modes; i++)
{
- mode = pScrPriv->modes[i];
+ mode = modes[i];
if (RRModeEqual (&mode->mode, modeInfo) &&
!memcmp (name, mode->name, modeInfo->nameLength))
{
@@ -71,16 +75,14 @@ RRModeGet (ScreenPtr pScreen,
mode->name = (char *) (mode + 1);
memcpy (mode->name, name, modeInfo->nameLength);
mode->name[modeInfo->nameLength] = '\0';
- mode->screen = pScreen;
mode->userDefined = FALSE;
- if (pScrPriv->numModes)
- modes = xrealloc (pScrPriv->modes,
- (pScrPriv->numModes + 1) * sizeof (RRModePtr));
+ if (num_modes)
+ newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr));
else
- modes = xalloc (sizeof (RRModePtr));
+ newModes = xalloc (sizeof (RRModePtr));
- if (!modes)
+ if (!newModes)
{
xfree (mode);
return NULL;
@@ -89,37 +91,64 @@ RRModeGet (ScreenPtr pScreen,
mode->mode.id = FakeClientID(0);
if (!AddResource (mode->mode.id, RRModeType, (pointer) mode))
return NULL;
+ modes = newModes;
+ modes[num_modes++] = mode;
+
+ /*
+ * give the caller a reference to this mode
+ */
++mode->refcnt;
- pScrPriv->modes = modes;
- pScrPriv->modes[pScrPriv->numModes++] = mode;
- pScrPriv->changed = TRUE;
return mode;
}
+RRModePtr *
+RRModesForScreen (ScreenPtr pScreen, int *num_ret)
+{
+ rrScrPriv(pScreen);
+ int o;
+ RRModePtr *screen_modes;
+ int num_screen_modes = 0;
+
+ screen_modes = xalloc ((num_modes ? num_modes : 1) * sizeof (RRModePtr));
+
+ for (o = 0; o < pScrPriv->numOutputs; o++)
+ {
+ RROutputPtr output = pScrPriv->outputs[o];
+ int m, n;
+
+ for (m = 0; m < output->numModes; m++)
+ {
+ RRModePtr mode = output->modes[m];
+ for (n = 0; n < num_screen_modes; n++)
+ if (screen_modes[n] == mode)
+ break;
+ if (n == num_screen_modes)
+ screen_modes[num_screen_modes++] = mode;
+ }
+ }
+ *num_ret = num_screen_modes;
+ return screen_modes;
+}
+
void
RRModeDestroy (RRModePtr mode)
{
- ScreenPtr pScreen;
- rrScrPrivPtr pScrPriv;
int m;
if (--mode->refcnt > 0)
return;
- pScreen = mode->screen;
- pScrPriv = rrGetScrPriv (pScreen);
- for (m = 0; m < pScrPriv->numModes; m++)
+ for (m = 0; m < num_modes; m++)
{
- if (pScrPriv->modes[m] == mode)
+ if (modes[m] == mode)
{
- memmove (pScrPriv->modes + m, pScrPriv->modes + m + 1,
- (pScrPriv->numModes - m - 1) * sizeof (RRModePtr));
- pScrPriv->numModes--;
- if (!pScrPriv->numModes)
+ memmove (modes + m, modes + m + 1,
+ (num_modes - m - 1) * sizeof (RRModePtr));
+ num_modes--;
+ if (!num_modes)
{
- xfree (pScrPriv->modes);
- pScrPriv->modes = NULL;
+ xfree (modes);
+ modes = NULL;
}
- pScrPriv->changed = TRUE;
break;
}
}
@@ -137,6 +166,8 @@ RRModeDestroyResource (pointer value, XID pid)
Bool
RRModeInit (void)
{
+ assert (num_modes == 0);
+ assert (modes == NULL);
RRModeType = CreateNewResourceType (RRModeDestroyResource);
if (!RRModeType)
return FALSE;
@@ -146,26 +177,6 @@ RRModeInit (void)
return TRUE;
}
-void
-RRModePruneUnused (ScreenPtr pScreen)
-{
- rrScrPriv (pScreen);
- RRModePtr *unused, mode;
- int m;
- int num = pScrPriv->numModes;
-
- unused = xalloc (num * sizeof (RRModePtr));
- if (!unused)
- return;
- memcpy (unused, pScrPriv->modes, num * sizeof (RRModePtr));
- for (m = 0; m < num; m++) {
- mode = unused[m];
- if (mode->refcnt == 1 && !mode->userDefined)
- FreeResource (mode->mode.id, 0);
- }
- xfree (unused);
-}
-
int
ProcRRCreateMode (ClientPtr client)
{
@@ -205,4 +216,3 @@ ProcRRDeleteOutputMode (ClientPtr client)
(void) stuff;
return BadImplementation;
}
-
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 1f6f33030..1b0ecab93 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -42,30 +42,17 @@ RROutputChanged (RROutputPtr output)
*/
RROutputPtr
-RROutputCreate (ScreenPtr pScreen,
- const char *name,
+RROutputCreate (const char *name,
int nameLength,
void *devPrivate)
{
- rrScrPriv (pScreen);
RROutputPtr output;
- RROutputPtr *outputs;
output = xalloc (sizeof (RROutputRec) + nameLength + 1);
if (!output)
return NULL;
- if (pScrPriv->numOutputs)
- outputs = xrealloc (pScrPriv->outputs,
- (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
- else
- outputs = xalloc (sizeof (RROutputPtr));
- if (!outputs)
- {
- xfree (output);
- return NULL;
- }
output->id = FakeClientID (0);
- output->pScreen = pScreen;
+ output->pScreen = NULL;
output->name = (char *) (output + 1);
output->nameLength = nameLength;
memcpy (output->name, name, nameLength);
@@ -91,12 +78,35 @@ RROutputCreate (ScreenPtr pScreen,
if (!AddResource (output->id, RROutputType, (pointer) output))
return NULL;
+ return output;
+}
+
+/*
+ * Attach an Output to a screen. This is done as a separate step
+ * so that an xf86-based driver can create Outputs in PreInit
+ * before the Screen has been created
+ */
+
+Bool
+RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen)
+{
+ rrScrPriv (pScreen);
+ RROutputPtr *outputs;
+
+ if (pScrPriv->numOutputs)
+ outputs = xrealloc (pScrPriv->outputs,
+ (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
+ else
+ outputs = xalloc (sizeof (RROutputPtr));
+ if (!outputs)
+ return FALSE;
+ output->pScreen = pScreen;
pScrPriv->outputs = outputs;
pScrPriv->outputs[pScrPriv->numOutputs++] = output;
RROutputChanged (output);
- return output;
+ return TRUE;
}
-
+
/*
* Notify extension that output parameters have been changed
*/
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index 705e7d78c..d47e9d60a 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -360,6 +360,13 @@ ProcRRGetScreenResources (ClientPtr client)
}
else
{
+ RRModePtr *modes;
+ int num_modes;
+
+ modes = RRModesForScreen (pScreen, &num_modes);
+ if (!modes)
+ return BadAlloc;
+
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
@@ -367,15 +374,15 @@ ProcRRGetScreenResources (ClientPtr client)
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.nCrtcs = pScrPriv->numCrtcs;
rep.nOutputs = pScrPriv->numOutputs;
- rep.nModes = pScrPriv->numModes;;
+ rep.nModes = num_modes;
rep.nbytesNames = 0;
- for (i = 0; i < pScrPriv->numModes; i++)
- rep.nbytesNames += pScrPriv->modes[i]->mode.nameLength;
+ for (i = 0; i < num_modes; i++)
+ rep.nbytesNames += modes[i]->mode.nameLength;
rep.length = (pScrPriv->numCrtcs +
pScrPriv->numOutputs +
- pScrPriv->numModes * (SIZEOF(xRRModeInfo) >> 2) +
+ num_modes * (SIZEOF(xRRModeInfo) >> 2) +
((rep.nbytesNames + 3) >> 2));
extraLen = rep.length << 2;
@@ -383,7 +390,10 @@ ProcRRGetScreenResources (ClientPtr client)
{
extra = xalloc (extraLen);
if (!extra)
+ {
+ xfree (modes);
return BadAlloc;
+ }
}
else
extra = NULL;
@@ -391,7 +401,7 @@ ProcRRGetScreenResources (ClientPtr client)
crtcs = (RRCrtc *) extra;
outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs);
modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs);
- names = (CARD8 *) (modeinfos + pScrPriv->numModes);
+ names = (CARD8 *) (modeinfos + num_modes);
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
@@ -407,9 +417,10 @@ ProcRRGetScreenResources (ClientPtr client)
swapl (&outputs[i], n);
}
- for (i = 0; i < pScrPriv->numModes; i++)
+ for (i = 0; i < num_modes; i++)
{
- modeinfos[i] = pScrPriv->modes[i]->mode;
+ RRModePtr mode = modes[i];
+ modeinfos[i] = mode->mode;
if (client->swapped)
{
swapl (&modeinfos[i].id, n);
@@ -426,10 +437,11 @@ ProcRRGetScreenResources (ClientPtr client)
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;
+ memcpy (names, mode->name,
+ mode->mode.nameLength);
+ names += mode->mode.nameLength;
}
+ xfree (modes);
assert (((((char *) names - (char *) extra) + 3) >> 2) == rep.length);
}