diff options
-rw-r--r-- | hw/xfree86/common/Makefile.am | 2 | ||||
-rw-r--r-- | randr/mirandr.c | 13 | ||||
-rw-r--r-- | randr/randr.c | 4 | ||||
-rw-r--r-- | randr/randrstr.h | 36 | ||||
-rw-r--r-- | randr/rrcrtc.c | 170 | ||||
-rw-r--r-- | randr/rrinfo.c | 14 | ||||
-rw-r--r-- | randr/rrmode.c | 108 | ||||
-rw-r--r-- | randr/rroutput.c | 44 | ||||
-rw-r--r-- | randr/rrscreen.c | 32 |
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); } |