xserver: Branch 'randr-1.2'
Keith Packard
keithp at kemper.freedesktop.org
Thu Nov 9 07:36:45 EET 2006
hw/xfree86/common/Makefile.am | 2
randr/mirandr.c | 13 ++-
randr/randr.c | 4
randr/randrstr.h | 36 ++++++--
randr/rrcrtc.c | 170 ++++++++++++++++++++++++------------------
randr/rrinfo.c | 14 ++-
randr/rrmode.c | 108 ++++++++++++++------------
randr/rroutput.c | 44 ++++++----
randr/rrscreen.c | 32 +++++--
9 files changed, 254 insertions(+), 169 deletions(-)
New commits:
diff-tree ec77a95a02329a2ee3a94d7de9d2a234aecb9ca0 (from 20e9144c0746943624ff77a61791b8596f3f8458)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date: Wed Nov 8 21:36:35 2006 -0800
Allow RandR objects to be created before the associated ScreenRec.
xf86 drivers need to create RandR object in the PreInit stage,
before the ScreenRec is allocated. Changing the RandR DIX code
to permit this required the addition of functions that later associate the
objects with the related screen.
An additional change is that modes are now global, and no longer associated
with a specific screen. This change actually makes mode management cleaner
as there is no more per-screen list of modes to deal with.
This changes the RandR 1.2 ABI/API for drivers.
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index 0e1582e..35b22f0 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
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 11c2991..3f56fe4 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 7b39e80..4426c47 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 60877a3..345418b 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 layo
* 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 76d0b6b..9f7177a 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)
+ if (pScreen)
{
- return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
- rotation, numOutputs, outputs);
- }
-#endif
-#if RANDR_10_INTERFACE
- if (pScrPriv->rrSetConfig)
- {
- 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, XI
{
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 e92caad..244b089 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -44,7 +44,7 @@ RROldModeAdd (RROutputPtr output, RRScre
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, Rota
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 fb4b5eb..3cd9ef2 100644
--- a/randr/rrmode.c
+++ b/randr/rrmode.c
@@ -42,19 +42,23 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo
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, XI
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 1f6f330..1b0ecab 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 705e7d7..d47e9d6 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -360,6 +360,13 @@ ProcRRGetScreenResources (ClientPtr clie
}
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 clie
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 clie
{
extra = xalloc (extraLen);
if (!extra)
+ {
+ xfree (modes);
return BadAlloc;
+ }
}
else
extra = NULL;
@@ -391,7 +401,7 @@ ProcRRGetScreenResources (ClientPtr clie
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 clie
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 clie
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);
}
More information about the xorg-commit
mailing list