summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--randr/Makefile.am1
-rw-r--r--randr/mirandr.c3
-rw-r--r--randr/randr.c72
-rw-r--r--randr/randrstr.h104
-rw-r--r--randr/rrcrtc.c53
-rw-r--r--randr/rroutput.c61
-rw-r--r--randr/rrpointer.c137
-rw-r--r--randr/rrproperty.c1
-rw-r--r--randr/rrscreen.c31
9 files changed, 415 insertions, 48 deletions
diff --git a/randr/Makefile.am b/randr/Makefile.am
index 91c4bc6dd..9bf0e6531 100644
--- a/randr/Makefile.am
+++ b/randr/Makefile.am
@@ -15,6 +15,7 @@ librandr_la_SOURCES = \
rrinfo.c \
rrmode.c \
rroutput.c \
+ rrpointer.c \
rrproperty.c \
rrscreen.c \
rrsdispatch.c \
diff --git a/randr/mirandr.c b/randr/mirandr.c
index 918e55da4..fab0fd1bd 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -84,6 +84,9 @@ miRandRInit (ScreenPtr pScreen)
pScrPriv->rrGetInfo = miRRGetInfo;
#if RANDR_12_INTERFACE
pScrPriv->rrCrtcSet = miRRCrtcSet;
+ pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
+ pScrPriv->rrOutputSetProperty = miRROutput
+
RRScreenSetSizeRange (pScreen,
pScreen->width, pScreen->height,
diff --git a/randr/randr.c b/randr/randr.c
index 35f9a4c80..b422efe9d 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -130,38 +130,71 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
cpswaps(from->subpixelOrder, to->subpixelOrder);
}
-#if 0
static void
-SRRMonitorChangeNotifyEvent(xRRMonitorChangeNotifyEvent *from,
- xRRMonitorChangeNotifyEvent *to)
+SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from,
+ xRRCrtcChangeNotifyEvent *to)
{
to->type = from->type;
to->subCode = from->subCode;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->timestamp, to->timestamp);
- cpswapl(from->configTimestamp, to->configTimestamp);
- cpswapl(from->root, to->root);
cpswapl(from->window, to->window);
- cpswaps(from->monitor, to->monitor);
- cpswaps(from->modeID, to->modeID);
+ cpswapl(from->crtc, to->crtc);
+ cpswapl(from->mode, to->mode);
+ cpswapl(from->window, to->window);
cpswaps(from->rotation, to->rotation);
- cpswaps(from->subpixelOrder, to->subpixelOrder);
cpswaps(from->x, to->x);
cpswaps(from->y, to->y);
+ cpswaps(from->width, to->width);
+ cpswaps(from->height, to->height);
+}
+
+static void
+SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from,
+ xRROutputChangeNotifyEvent *to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->configTimestamp, to->configTimestamp);
+ cpswapl(from->window, to->window);
+ cpswapl(from->output, to->output);
+ cpswapl(from->crtc, to->crtc);
+ cpswapl(from->mode, to->mode);
+ cpswaps(from->rotation, to->rotation);
+}
+
+static void
+SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from,
+ xRROutputPropertyNotifyEvent *to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->window, to->window);
+ cpswapl(from->output, to->output);
+ cpswapl(from->atom, to->atom);
+ cpswapl(from->timestamp, to->timestamp);
}
-#endif
static void
SRRNotifyEvent (xEvent *from,
xEvent *to)
{
switch (from->u.u.detail) {
-#if 0
- case RRNotify_MonitorChange:
- SRRMonitorChangeNotifyEvent ((xRRMonitorChangeNotifyEvent *) from,
- (xRRMonitorChangeNotifyEvent *) to);
+ case RRNotify_CrtcChange:
+ SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from,
+ (xRRCrtcChangeNotifyEvent *) to);
+ break;
+ case RRNotify_OutputChange:
+ SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from,
+ (xRROutputChangeNotifyEvent *) to);
+ break;
+ case RRNotify_OutputProperty:
+ SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from,
+ (xRROutputPropertyNotifyEvent *) to);
break;
-#endif
default:
break;
}
@@ -359,6 +392,9 @@ TellChanged (WindowPtr pWin, pointer value)
return WT_WALKCHILDREN;
}
+/*
+ * Something changed; send events and adjust pointer position
+ */
void
RRTellChanged (ScreenPtr pScreen)
{
@@ -369,12 +405,18 @@ RRTellChanged (ScreenPtr pScreen)
{
UpdateCurrentTime ();
pScrPriv->lastConfigTime = currentTime;
- WalkTree (pScreen, TellChanged, (pointer) pScreen);
pScrPriv->changed = FALSE;
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
for (i = 0; i < pScrPriv->numOutputs; i++)
pScrPriv->outputs[i]->changed = FALSE;
for (i = 0; i < pScrPriv->numCrtcs; i++)
pScrPriv->crtcs[i]->changed = FALSE;
+ if (pScrPriv->layoutChanged)
+ {
+ pScrPriv->layoutChanged = FALSE;
+ RRPointerScreenConfigured (pScreen);
+ RRSendConfigNotify (pScreen);
+ }
}
}
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 6690556b4..a8a995026 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -202,10 +202,11 @@ typedef struct _rrScrPriv {
TimeStamp lastSetTime; /* last changed by client */
TimeStamp lastConfigTime; /* possible configs changed */
RRCloseScreenProcPtr CloseScreen;
- Bool changed;
+ Bool changed; /* some config changed */
CARD16 minWidth, minHeight;
CARD16 maxWidth, maxHeight;
CARD16 width, height; /* last known screen size */
+ Bool layoutChanged; /* screen layout changed */
/* modes, outputs and crtcs */
int numModes;
@@ -217,6 +218,9 @@ typedef struct _rrScrPriv {
int numCrtcs;
RRCrtcPtr *crtcs;
+ /* Last known pointer position */
+ RRCrtcPtr pointerCrtc;
+
#ifdef RANDR_10_INTERFACE
/*
* Configuration information
@@ -439,6 +443,14 @@ RRSetScreenConfig (ScreenPtr pScreen,
#endif
/* rrcrtc.c */
+
+/*
+ * Notify the CRTC of some change; layoutChanged indicates that
+ * some position or size element changed
+ */
+void
+RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
+
/*
* Create a CRTC
*/
@@ -575,6 +587,13 @@ int
ProcRRDeleteOutputMode (ClientPtr client);
/* rroutput.c */
+
+/*
+ * Notify the output of some change
+ */
+void
+RROutputChanged (RROutputPtr output);
+
/*
* Create an output
*/
@@ -638,6 +657,13 @@ ProcRRGetOutputInfo (ClientPtr client);
Bool
RROutputInit (void);
+/* rrpointer.c */
+void
+RRPointerMoved (ScreenPtr pScreen, int x, int y);
+
+void
+RRPointerScreenConfigured (ScreenPtr pScreen);
+
/* rrproperty.c */
void
@@ -668,3 +694,79 @@ void
RRXineramaExtensionInit(void);
#endif /* _RANDRSTR_H_ */
+
+/*
+
+randr extension implementation structure
+
+Query state:
+ ProcRRGetScreenInfo/ProcRRGetScreenResources
+ RRGetInfo
+
+ • Request configuration from driver, either 1.0 or 1.2 style
+ • These functions only record state changes, all
+ other actions are pended until RRTellChanged is called
+
+ ->rrGetInfo
+ 1.0:
+ RRRegisterSize
+ RRRegisterRate
+ RRSetCurrentConfig
+ 1.2:
+ RRScreenSetSizeRange
+ RROutputSetCrtcs
+ RROutputSetCrtc
+ RROutputSetPossibleOptions
+ RRSetCurrentOptions
+ RRModeGet
+ RROutputSetModes
+ RROutputSetConnection
+ RROutputSetSubpixelOrder
+ RROutputSetClones
+ RRCrtcNotify
+
+ • Must delay scanning configuration until after ->rrGetInfo returns
+ because some drivers will call SetCurrentConfig in the middle
+ of the ->rrGetInfo operation.
+
+ 1.0:
+
+ • Scan old configuration, mirror to new structures
+
+ RRScanOldConfig
+ RRCrtcCreate
+ RROutputCreate
+ RROutputSetCrtcs
+ RROutputSetCrtc
+ RROutputSetConnection
+ RROutputSetSubpixelOrder
+ RROldModeAdd • This adds modes one-at-a-time
+ RRModeGet
+ RRCrtcNotify
+
+ • send events, reset pointer if necessary
+
+ RRTellChanged
+ WalkTree (sending events)
+
+ • when layout has changed:
+ RRPointerScreenConfigured
+ RRSendConfigNotify
+
+Asynchronous state setting (1.2 only)
+ When setting state asynchronously, the driver invokes the
+ ->rrGetInfo function and then calls RRTellChanged to flush
+ the changes to the clients and reset pointer if necessary
+
+Set state
+
+ ProcRRSetScreenConfig
+ RRCrtcSet
+ 1.2:
+ ->rrCrtcSet
+ RRCrtcNotify
+ 1.0:
+ ->rrSetConfig
+ RRCrtcNotify
+ RRTellChanged
+ */
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index baefd3a15..c662899a4 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -26,6 +26,24 @@
RESTYPE RRCrtcType;
/*
+ * Notify the CRTC of some change
+ */
+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;
+}
+
+/*
* Create a CRTC
*/
RRCrtcPtr
@@ -60,7 +78,7 @@ RRCrtcCreate (ScreenPtr pScreen,
crtc->numOutputs = 0;
crtc->gammaSize = 0;
crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
- crtc->changed = TRUE;
+ crtc->changed = FALSE;
crtc->devPrivate = devPrivate;
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
@@ -68,7 +86,8 @@ RRCrtcCreate (ScreenPtr pScreen,
pScrPriv->crtcs = crtcs;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
- pScrPriv->changed = TRUE;
+
+ RRCrtcChanged (crtc, TRUE);
return crtc;
}
@@ -85,8 +104,6 @@ RRCrtcNotify (RRCrtcPtr crtc,
int numOutputs,
RROutputPtr *outputs)
{
- ScreenPtr pScreen = crtc->pScreen;
- rrScrPriv(pScreen);
int i, j;
/*
@@ -100,8 +117,8 @@ RRCrtcNotify (RRCrtcPtr crtc,
break;
if (j == crtc->numOutputs)
{
- outputs[i]->changed = TRUE;
- crtc->changed = TRUE;
+ RROutputChanged (outputs[i]);
+ RRCrtcChanged (crtc, FALSE);
}
}
/*
@@ -115,8 +132,8 @@ RRCrtcNotify (RRCrtcPtr crtc,
break;
if (i == numOutputs)
{
- crtc->outputs[j]->changed = TRUE;
- crtc->changed = TRUE;
+ RROutputChanged (crtc->outputs[j]);
+ RRCrtcChanged (crtc, FALSE);
}
}
/*
@@ -158,31 +175,22 @@ RRCrtcNotify (RRCrtcPtr crtc,
RRModeDestroy (crtc->mode);
crtc->mode = mode;
mode->refcnt++;
- crtc->changed = TRUE;
+ RRCrtcChanged (crtc, TRUE);
}
if (x != crtc->x)
{
crtc->x = x;
- crtc->changed = TRUE;
+ RRCrtcChanged (crtc, TRUE);
}
if (y != crtc->y)
{
crtc->y = y;
- crtc->changed = TRUE;
+ RRCrtcChanged (crtc, TRUE);
}
if (rotation != crtc->rotation)
{
crtc->rotation = rotation;
- crtc->changed = TRUE;
- }
- /*
- * Send events if anything changed
- */
- if (crtc->changed)
- {
- if (!pScrPriv->changed)
- RRSendConfigNotify (pScreen);
- pScrPriv->changed = TRUE;
+ RRCrtcChanged (crtc, TRUE);
}
return TRUE;
}
@@ -272,10 +280,11 @@ RRCrtcSet (RRCrtcPtr crtc,
* Old 1.0 interface tied screen size to mode size
*/
if (ret)
- RRScreenSizeNotify (pScreen);
+ RRCrtcNotify (crtc, mode, x, y, rotation,
return ret;
}
#endif
+ RRTellChanged (pScreen);
return FALSE;
}
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 618ef1f80..fc84ec1e6 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -25,6 +25,19 @@
RESTYPE RROutputType;
/*
+ * Notify the output of some change
+ */
+void
+RROutputChanged (RROutputPtr output)
+{
+ ScreenPtr pScreen = output->pScreen;
+ rrScrPriv (pScreen);
+
+ output->changed = TRUE;
+ pScrPriv->changed = TRUE;
+}
+
+/*
* Create an output
*/
@@ -70,7 +83,7 @@ RROutputCreate (ScreenPtr pScreen,
output->numPreferred = 0;
output->modes = NULL;
output->properties = NULL;
- output->changed = TRUE;
+ output->changed = FALSE;
output->devPrivate = devPrivate;
if (!AddResource (output->id, RROutputType, (pointer) output))
@@ -78,7 +91,7 @@ RROutputCreate (ScreenPtr pScreen,
pScrPriv->outputs = outputs;
pScrPriv->outputs[pScrPriv->numOutputs++] = output;
- pScrPriv->changed = TRUE;
+ RROutputChanged (output);
return output;
}
@@ -114,7 +127,7 @@ RROutputSetClones (RROutputPtr output,
memcpy (newClones, clones, numClones * sizeof (RROutputPtr));
output->clones = newClones;
output->numClones = numClones;
- output->changed = TRUE;
+ RROutputChanged (output);
return TRUE;
}
@@ -158,7 +171,7 @@ RROutputSetModes (RROutputPtr output,
output->modes = newModes;
output->numModes = numModes;
output->numPreferred = numPreferred;
- output->changed = TRUE;
+ RROutputChanged (output);
return TRUE;
}
@@ -191,7 +204,7 @@ RROutputSetCrtcs (RROutputPtr output,
memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr));
output->crtcs = newCrtcs;
output->numCrtcs = numCrtcs;
- output->changed = TRUE;
+ RROutputChanged (output);
return TRUE;
}
@@ -202,7 +215,7 @@ RROutputSetPossibleOptions (RROutputPtr output,
if (output->possibleOptions == possibleOptions)
return TRUE;
output->possibleOptions = possibleOptions;
- output->changed = TRUE;
+ RROutputChanged (output);
return TRUE;
}
@@ -212,7 +225,7 @@ RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc)
if (output->crtc == crtc)
return;
output->crtc = crtc;
- output->changed = TRUE;
+ RROutputChanged (output);
}
Bool
@@ -222,7 +235,7 @@ RROutputSetConnection (RROutputPtr output,
if (output->connection == connection)
return TRUE;
output->connection = connection;
- output->changed = TRUE;
+ RROutputChanged (output);
return TRUE;
}
@@ -234,7 +247,7 @@ RROutputSetSubpixelOrder (RROutputPtr output,
return TRUE;
output->subpixelOrder = subpixelOrder;
- output->changed = TRUE;
+ RROutputChanged (output);
return TRUE;
}
@@ -245,13 +258,41 @@ RROutputSetCurrentOptions (RROutputPtr output,
if (output->currentOptions == currentOptions)
return TRUE;
output->currentOptions = currentOptions;
- output->changed = TRUE;
+ RROutputChanged (output);
return TRUE;
}
void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv (pScreen);
+ xRROutputChangeNotifyEvent oe;
+ RRCrtcPtr crtc = output->crtc;
+ RRModePtr mode = crtc ? crtc->mode : 0;
+
+ oe.type = RRNotify + RREventBase;
+ oe.subCode = RRNotify_OutputChange;
+ oe.sequenceNumber = client->sequence;
+ oe.timestamp = pScrPriv->lastSetTime.milliseconds;
+ oe.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ oe.window = pWin->drawable.id;
+ oe.output = output->id;
+ if (crtc)
+ {
+ oe.crtc = crtc->id;
+ oe.mode = mode ? mode->mode.id : None;
+ oe.rotation = crtc->rotation;
+ }
+ else
+ {
+ oe.crtc = None;
+ oe.mode = None;
+ oe.rotation = RR_Rotate_0;
+ }
+ oe.connection = output->connection;
+ oe.subpixelOrder = output->subpixelOrder;
+ WriteEventsToClient (client, 1, (xEvent *) &oe);
}
/*
diff --git a/randr/rrpointer.c b/randr/rrpointer.c
new file mode 100644
index 000000000..7ba0460f5
--- /dev/null
+++ b/randr/rrpointer.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+
+/*
+ * When the pointer moves, check to see if the specified position is outside
+ * any of theavailable CRTCs and move it to a 'sensible' place if so, where
+ * sensible is the closest monitor to the departing edge.
+ *
+ * Returns whether the position was adjusted
+ */
+
+static Bool
+RRCrtcContainsPosition (RRCrtcPtr crtc, int x, int y)
+{
+ RRModePtr mode = crtc->mode;
+
+ if (!mode)
+ return FALSE;
+ if (crtc->x <= x && x < crtc->x + mode->mode.width &&
+ crtc->y <= y && y < crtc->y + mode->mode.height)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Find the CRTC nearest the specified position, ignoring 'skip'
+ */
+static void
+RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
+{
+ rrScrPriv (pScreen);
+ int c;
+ RRCrtcPtr nearest = NULL;
+ int best = 0;
+ int best_dx = 0, best_dy = 0;
+
+ for (c = 0; c < pScrPriv->numCrtcs; c++)
+ {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+ RRModePtr mode = crtc->mode;
+ int dx, dy;
+ int dist;
+
+ if (!mode)
+ continue;
+ if (crtc == skip)
+ continue;
+ if (x < crtc->x)
+ dx = crtc->x - x;
+ else if (x > crtc->x + mode->mode.width)
+ dx = x - (crtc->x + mode->mode.width);
+ else
+ dx = 0;
+ if (y < crtc->y)
+ dy = crtc->y - x;
+ else if (y > crtc->y + mode->mode.height)
+ dy = y - (crtc->y + mode->mode.height);
+ else
+ dy = 0;
+ dist = dx + dy;
+ if (!nearest || dist < best)
+ {
+ nearest = crtc;
+ best_dx = dx;
+ best_dy = dy;
+ }
+ }
+ if (best_dx || best_dy)
+ (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE);
+ pScrPriv->pointerCrtc = nearest;
+}
+
+void
+RRPointerMoved (ScreenPtr pScreen, int x, int y)
+{
+ rrScrPriv (pScreen);
+ RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc;;
+ int c;
+
+ /* Check last known CRTC */
+ if (pointerCrtc && RRCrtcContainsPosition (pointerCrtc, x, y))
+ return;
+
+ /* Check all CRTCs */
+ for (c = 0; c < pScrPriv->numCrtcs; c++)
+ {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+
+ if (RRCrtcContainsPosition (crtc, x, y))
+ {
+ /* Remember containing CRTC */
+ pScrPriv->pointerCrtc = crtc;
+ return;
+ }
+ }
+
+ /* None contain pointer, find nearest */
+ RRPointerToNearestCrtc (pScreen, x, y, pointerCrtc);
+}
+
+/*
+ * When the screen is reconfigured, move the pointer to the nearest
+ * CRTC
+ */
+void
+RRPointerScreenConfigured (ScreenPtr pScreen)
+{
+ WindowPtr pRoot = GetCurrentRootWindow ();
+ ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+ int x, y;
+
+ if (pScreen != pCurrentScreen)
+ return FALSE;
+ GetSpritePosition (&x, &y);
+ RRPointerToNearestCrtc (pScreen, x, y, NULL);
+}
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index cdafb5c9b..44f1f0ace 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -27,6 +27,7 @@
static void
RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask)
{
+
}
void
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index 7b53f0468..6d38e96b5 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -164,10 +164,13 @@ RRScreenSizeNotify (ScreenPtr pScreen)
pScrPriv->width = pScreen->width;
pScrPriv->height = pScreen->height;
pScrPriv->changed = TRUE;
+ pScrPriv->sizeChanged = TRUE;
+ RRTellChanged (pScreen);
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
+ RRPointerScreenConfigured (pScreen);
/*
* Fix pointer bounds and location
*/
@@ -836,9 +839,37 @@ ProcRRSetScreenConfig (ClientPtr client)
goto sendReply;
}
+ /*
+ * If the screen size is changing, adjust all of the other outputs
+ * to fit the new size, mirroring as much as possible
+ */
+ if (mode->mode.width != pScreen->width ||
+ mode->mode.height != pScreen->height)
+ {
+ int c;
+
+ for (c = 0; c < pScrPriv->numCrtcs; c++)
+ {
+ rep.status = RRCrtcSet (pScrPriv->->crtc, NULL, 0, 0, RR_Rotate_0,
+ 0, NULL);
+ if (rep.status != Success)
+ goto sendReply;
+ }
+ if (!RRScreenSizeSet (pScreen, mode->mode.width, mode->mode.height,
+ pScreen->mmWidth, pScreen->mmHeight))
+ {
+ rep.status RRSetConfigFailed;
+ goto sendReply;
+ }
+ }
+
rep.status = RRCrtcSet (output.output->crtc, mode, 0, 0, stuff->rotation,
1, &output);
+ /*
+ * XXX Configure other crtcs to mirror as much as possible
+ */
+
sendReply:
if (pData)