diff options
Diffstat (limited to 'xorg-server/randr/rroutput.c')
-rw-r--r-- | xorg-server/randr/rroutput.c | 1242 |
1 files changed, 621 insertions, 621 deletions
diff --git a/xorg-server/randr/rroutput.c b/xorg-server/randr/rroutput.c index 3a1b8bbea..a65b45912 100644 --- a/xorg-server/randr/rroutput.c +++ b/xorg-server/randr/rroutput.c @@ -1,621 +1,621 @@ -/* - * Copyright © 2006 Keith Packard - * Copyright © 2008 Red Hat, Inc. - * - * 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" - -RESTYPE RROutputType; - -/* - * Notify the output of some change - */ -void -RROutputChanged (RROutputPtr output, Bool configChanged) -{ - ScreenPtr pScreen = output->pScreen; - - output->changed = TRUE; - if (pScreen) - { - rrScrPriv (pScreen); - pScrPriv->changed = TRUE; - if (configChanged) - pScrPriv->configChanged = TRUE; - } -} - -/* - * Create an output - */ - -RROutputPtr -RROutputCreate (ScreenPtr pScreen, - const char *name, - int nameLength, - void *devPrivate) -{ - RROutputPtr output; - RROutputPtr *outputs; - rrScrPrivPtr pScrPriv; - - if (!RRInit()) - return NULL; - - pScrPriv = rrGetScrPriv(pScreen); - - if (pScrPriv->numOutputs) - outputs = xrealloc (pScrPriv->outputs, - (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr)); - else - outputs = xalloc (sizeof (RROutputPtr)); - if (!outputs) - return FALSE; - - pScrPriv->outputs = outputs; - - output = xalloc (sizeof (RROutputRec) + nameLength + 1); - if (!output) - return NULL; - output->id = FakeClientID (0); - output->pScreen = pScreen; - output->name = (char *) (output + 1); - output->nameLength = nameLength; - memcpy (output->name, name, nameLength); - output->name[nameLength] = '\0'; - output->connection = RR_UnknownConnection; - output->subpixelOrder = SubPixelUnknown; - output->mmWidth = 0; - output->mmHeight = 0; - output->crtc = NULL; - output->numCrtcs = 0; - output->crtcs = NULL; - output->numClones = 0; - output->clones = NULL; - output->numModes = 0; - output->numPreferred = 0; - output->modes = NULL; - output->numUserModes = 0; - output->userModes = NULL; - output->properties = NULL; - output->pendingProperties = FALSE; - output->changed = FALSE; - output->devPrivate = devPrivate; - - if (!AddResource (output->id, RROutputType, (pointer) output)) - return NULL; - - pScrPriv->outputs[pScrPriv->numOutputs++] = output; - return output; -} - -/* - * Notify extension that output parameters have been changed - */ -Bool -RROutputSetClones (RROutputPtr output, - RROutputPtr *clones, - int numClones) -{ - RROutputPtr *newClones; - int i; - - if (numClones == output->numClones) - { - for (i = 0; i < numClones; i++) - if (output->clones[i] != clones[i]) - break; - if (i == numClones) - return TRUE; - } - if (numClones) - { - newClones = xalloc (numClones * sizeof (RROutputPtr)); - if (!newClones) - return FALSE; - } - else - newClones = NULL; - if (output->clones) - xfree (output->clones); - memcpy (newClones, clones, numClones * sizeof (RROutputPtr)); - output->clones = newClones; - output->numClones = numClones; - RROutputChanged (output, TRUE); - return TRUE; -} - -Bool -RROutputSetModes (RROutputPtr output, - RRModePtr *modes, - int numModes, - int numPreferred) -{ - RRModePtr *newModes; - int i; - - if (numModes == output->numModes && numPreferred == output->numPreferred) - { - for (i = 0; i < numModes; i++) - if (output->modes[i] != modes[i]) - break; - if (i == numModes) - { - for (i = 0; i < numModes; i++) - RRModeDestroy (modes[i]); - return TRUE; - } - } - - if (numModes) - { - newModes = xalloc (numModes * sizeof (RRModePtr)); - if (!newModes) - return FALSE; - } - else - newModes = NULL; - if (output->modes) - { - for (i = 0; i < output->numModes; i++) - RRModeDestroy (output->modes[i]); - xfree (output->modes); - } - memcpy (newModes, modes, numModes * sizeof (RRModePtr)); - output->modes = newModes; - output->numModes = numModes; - output->numPreferred = numPreferred; - RROutputChanged (output, TRUE); - return TRUE; -} - -int -RROutputAddUserMode (RROutputPtr output, - RRModePtr mode) -{ - int m; - ScreenPtr pScreen = output->pScreen; - rrScrPriv(pScreen); - RRModePtr *newModes; - - /* Check to see if this mode is already listed for this output */ - for (m = 0; m < output->numModes + output->numUserModes; m++) - { - RRModePtr e = (m < output->numModes ? - output->modes[m] : - output->userModes[m - output->numModes]); - if (mode == e) - return Success; - } - - /* Check with the DDX to see if this mode is OK */ - if (pScrPriv->rrOutputValidateMode) - if (!pScrPriv->rrOutputValidateMode (pScreen, output, mode)) - return BadMatch; - - if (output->userModes) - newModes = xrealloc (output->userModes, - (output->numUserModes + 1) * sizeof (RRModePtr)); - else - newModes = xalloc (sizeof (RRModePtr)); - if (!newModes) - return BadAlloc; - - output->userModes = newModes; - output->userModes[output->numUserModes++] = mode; - ++mode->refcnt; - RROutputChanged (output, TRUE); - RRTellChanged (pScreen); - return Success; -} - -int -RROutputDeleteUserMode (RROutputPtr output, - RRModePtr mode) -{ - int m; - - /* Find this mode in the user mode list */ - for (m = 0; m < output->numUserModes; m++) - { - RRModePtr e = output->userModes[m]; - - if (mode == e) - break; - } - /* Not there, access error */ - if (m == output->numUserModes) - return BadAccess; - - /* make sure the mode isn't active for this output */ - if (output->crtc && output->crtc->mode == mode) - return BadMatch; - - memmove (output->userModes + m, output->userModes + m + 1, - (output->numUserModes - m - 1) * sizeof (RRModePtr)); - output->numUserModes--; - RRModeDestroy (mode); - return Success; -} - -Bool -RROutputSetCrtcs (RROutputPtr output, - RRCrtcPtr *crtcs, - int numCrtcs) -{ - RRCrtcPtr *newCrtcs; - int i; - - if (numCrtcs == output->numCrtcs) - { - for (i = 0; i < numCrtcs; i++) - if (output->crtcs[i] != crtcs[i]) - break; - if (i == numCrtcs) - return TRUE; - } - if (numCrtcs) - { - newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr)); - if (!newCrtcs) - return FALSE; - } - else - newCrtcs = NULL; - if (output->crtcs) - xfree (output->crtcs); - memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr)); - output->crtcs = newCrtcs; - output->numCrtcs = numCrtcs; - RROutputChanged (output, TRUE); - return TRUE; -} - -Bool -RROutputSetConnection (RROutputPtr output, - CARD8 connection) -{ - if (output->connection == connection) - return TRUE; - output->connection = connection; - RROutputChanged (output, TRUE); - return TRUE; -} - -Bool -RROutputSetSubpixelOrder (RROutputPtr output, - int subpixelOrder) -{ - if (output->subpixelOrder == subpixelOrder) - return TRUE; - - output->subpixelOrder = subpixelOrder; - RROutputChanged (output, FALSE); - return TRUE; -} - -Bool -RROutputSetPhysicalSize (RROutputPtr output, - int mmWidth, - int mmHeight) -{ - if (output->mmWidth == mmWidth && output->mmHeight == mmHeight) - return TRUE; - output->mmWidth = mmWidth; - output->mmHeight = mmHeight; - RROutputChanged (output, FALSE); - 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); -} - -/* - * Destroy a Output at shutdown - */ -void -RROutputDestroy (RROutputPtr output) -{ - FreeResource (output->id, 0); -} - -static int -RROutputDestroyResource (pointer value, XID pid) -{ - RROutputPtr output = (RROutputPtr) value; - ScreenPtr pScreen = output->pScreen; - int m; - - if (pScreen) - { - rrScrPriv(pScreen); - int i; - - if (pScrPriv->primaryOutput == output) - pScrPriv->primaryOutput = NULL; - - for (i = 0; i < pScrPriv->numOutputs; i++) - { - if (pScrPriv->outputs[i] == output) - { - memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1, - (pScrPriv->numOutputs - (i + 1)) * sizeof (RROutputPtr)); - --pScrPriv->numOutputs; - break; - } - } - } - if (output->modes) - { - for (m = 0; m < output->numModes; m++) - RRModeDestroy (output->modes[m]); - xfree (output->modes); - } - - for (m = 0; m < output->numUserModes; m++) - RRModeDestroy (output->userModes[m]); - if (output->userModes) - xfree (output->userModes); - - if (output->crtcs) - xfree (output->crtcs); - if (output->clones) - xfree (output->clones); - RRDeleteAllOutputProperties (output); - xfree (output); - return 1; -} - -/* - * Initialize output type - */ -Bool -RROutputInit (void) -{ - RROutputType = CreateNewResourceType (RROutputDestroyResource, "OUTPUT"); - if (!RROutputType) - return FALSE; - return TRUE; -} - -#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) - -int -ProcRRGetOutputInfo (ClientPtr client) -{ - REQUEST(xRRGetOutputInfoReq); - xRRGetOutputInfoReply rep; - RROutputPtr output; - CARD8 *extra; - unsigned long extraLen; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRCrtc *crtcs; - RRMode *modes; - RROutput *clones; - char *name; - int i, n; - - REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); - VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); - - pScreen = output->pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = bytes_to_int32(OutputInfoExtra); - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.crtc = output->crtc ? output->crtc->id : None; - rep.mmWidth = output->mmWidth; - rep.mmHeight = output->mmHeight; - rep.connection = output->connection; - rep.subpixelOrder = output->subpixelOrder; - rep.nCrtcs = output->numCrtcs; - rep.nModes = output->numModes + output->numUserModes; - rep.nPreferred = output->numPreferred; - rep.nClones = output->numClones; - rep.nameLength = output->nameLength; - - extraLen = ((output->numCrtcs + - output->numModes + output->numUserModes + - output->numClones + - bytes_to_int32(rep.nameLength)) << 2); - - if (extraLen) - { - rep.length += bytes_to_int32(extraLen); - extra = xalloc (extraLen); - if (!extra) - return BadAlloc; - } - else - extra = NULL; - - crtcs = (RRCrtc *) extra; - modes = (RRMode *) (crtcs + output->numCrtcs); - clones = (RROutput *) (modes + output->numModes + output->numUserModes); - name = (char *) (clones + output->numClones); - - for (i = 0; i < output->numCrtcs; i++) - { - crtcs[i] = output->crtcs[i]->id; - if (client->swapped) - swapl (&crtcs[i], n); - } - for (i = 0; i < output->numModes + output->numUserModes; i++) - { - if (i < output->numModes) - modes[i] = output->modes[i]->mode.id; - else - modes[i] = output->userModes[i - output->numModes]->mode.id; - if (client->swapped) - swapl (&modes[i], n); - } - for (i = 0; i < output->numClones; i++) - { - clones[i] = output->clones[i]->id; - if (client->swapped) - swapl (&clones[i], n); - } - memcpy (name, output->name, output->nameLength); - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swapl(&rep.crtc, n); - swapl(&rep.mmWidth, n); - swapl(&rep.mmHeight, n); - swaps(&rep.nCrtcs, n); - swaps(&rep.nModes, n); - swaps(&rep.nClones, n); - swaps(&rep.nameLength, n); - } - WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - - return client->noClientException; -} - -static void -RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv, - RROutputPtr output) -{ - if (pScrPriv->primaryOutput == output) - return; - - /* clear the old primary */ - if (pScrPriv->primaryOutput) { - RROutputChanged(pScrPriv->primaryOutput, 0); - pScrPriv->primaryOutput = NULL; - } - - /* set the new primary */ - if (output) { - pScrPriv->primaryOutput = output; - RROutputChanged(output, 0); - } - - pScrPriv->layoutChanged = TRUE; - - RRTellChanged(pScreen); -} - -int -ProcRRSetOutputPrimary(ClientPtr client) -{ - REQUEST(xRRSetOutputPrimaryReq); - RROutputPtr output = NULL; - WindowPtr pWin; - rrScrPrivPtr pScrPriv; - int rc; - - REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); - - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - if (stuff->output) { - VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); - - if (output->pScreen != pWin->drawable.pScreen) { - client->errorValue = stuff->window; - return BadMatch; - } - } - - pScrPriv = rrGetScrPriv(pWin->drawable.pScreen); - RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output); - - return client->noClientException; -} - -int -ProcRRGetOutputPrimary(ClientPtr client) -{ - REQUEST(xRRGetOutputPrimaryReq); - WindowPtr pWin; - rrScrPrivPtr pScrPriv; - xRRGetOutputPrimaryReply rep; - RROutputPtr primary = NULL; - int rc; - - REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); - - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - pScrPriv = rrGetScrPriv(pWin->drawable.pScreen); - if (pScrPriv) - primary = pScrPriv->primaryOutput; - - memset(&rep, 0, sizeof(rep)); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.output = primary ? primary->id : None; - - if (client->swapped) { - int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.output, n); - } - - WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), &rep); - - return client->noClientException; -} +/*
+ * Copyright © 2006 Keith Packard
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * 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"
+
+RESTYPE RROutputType;
+
+/*
+ * Notify the output of some change
+ */
+void
+RROutputChanged (RROutputPtr output, Bool configChanged)
+{
+ ScreenPtr pScreen = output->pScreen;
+
+ output->changed = TRUE;
+ if (pScreen)
+ {
+ rrScrPriv (pScreen);
+ pScrPriv->changed = TRUE;
+ if (configChanged)
+ pScrPriv->configChanged = TRUE;
+ }
+}
+
+/*
+ * Create an output
+ */
+
+RROutputPtr
+RROutputCreate (ScreenPtr pScreen,
+ const char *name,
+ int nameLength,
+ void *devPrivate)
+{
+ RROutputPtr output;
+ RROutputPtr *outputs;
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRInit())
+ return NULL;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv->numOutputs)
+ outputs = realloc(pScrPriv->outputs,
+ (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
+ else
+ outputs = malloc(sizeof (RROutputPtr));
+ if (!outputs)
+ return FALSE;
+
+ pScrPriv->outputs = outputs;
+
+ output = malloc(sizeof (RROutputRec) + nameLength + 1);
+ if (!output)
+ return NULL;
+ output->id = FakeClientID (0);
+ output->pScreen = pScreen;
+ output->name = (char *) (output + 1);
+ output->nameLength = nameLength;
+ memcpy (output->name, name, nameLength);
+ output->name[nameLength] = '\0';
+ output->connection = RR_UnknownConnection;
+ output->subpixelOrder = SubPixelUnknown;
+ output->mmWidth = 0;
+ output->mmHeight = 0;
+ output->crtc = NULL;
+ output->numCrtcs = 0;
+ output->crtcs = NULL;
+ output->numClones = 0;
+ output->clones = NULL;
+ output->numModes = 0;
+ output->numPreferred = 0;
+ output->modes = NULL;
+ output->numUserModes = 0;
+ output->userModes = NULL;
+ output->properties = NULL;
+ output->pendingProperties = FALSE;
+ output->changed = FALSE;
+ output->devPrivate = devPrivate;
+
+ if (!AddResource (output->id, RROutputType, (pointer) output))
+ return NULL;
+
+ pScrPriv->outputs[pScrPriv->numOutputs++] = output;
+ return output;
+}
+
+/*
+ * Notify extension that output parameters have been changed
+ */
+Bool
+RROutputSetClones (RROutputPtr output,
+ RROutputPtr *clones,
+ int numClones)
+{
+ RROutputPtr *newClones;
+ int i;
+
+ if (numClones == output->numClones)
+ {
+ for (i = 0; i < numClones; i++)
+ if (output->clones[i] != clones[i])
+ break;
+ if (i == numClones)
+ return TRUE;
+ }
+ if (numClones)
+ {
+ newClones = malloc(numClones * sizeof (RROutputPtr));
+ if (!newClones)
+ return FALSE;
+ }
+ else
+ newClones = NULL;
+ if (output->clones)
+ free(output->clones);
+ memcpy (newClones, clones, numClones * sizeof (RROutputPtr));
+ output->clones = newClones;
+ output->numClones = numClones;
+ RROutputChanged (output, TRUE);
+ return TRUE;
+}
+
+Bool
+RROutputSetModes (RROutputPtr output,
+ RRModePtr *modes,
+ int numModes,
+ int numPreferred)
+{
+ RRModePtr *newModes;
+ int i;
+
+ if (numModes == output->numModes && numPreferred == output->numPreferred)
+ {
+ for (i = 0; i < numModes; i++)
+ if (output->modes[i] != modes[i])
+ break;
+ if (i == numModes)
+ {
+ for (i = 0; i < numModes; i++)
+ RRModeDestroy (modes[i]);
+ return TRUE;
+ }
+ }
+
+ if (numModes)
+ {
+ newModes = malloc(numModes * sizeof (RRModePtr));
+ if (!newModes)
+ return FALSE;
+ }
+ else
+ newModes = NULL;
+ if (output->modes)
+ {
+ for (i = 0; i < output->numModes; i++)
+ RRModeDestroy (output->modes[i]);
+ free(output->modes);
+ }
+ memcpy (newModes, modes, numModes * sizeof (RRModePtr));
+ output->modes = newModes;
+ output->numModes = numModes;
+ output->numPreferred = numPreferred;
+ RROutputChanged (output, TRUE);
+ return TRUE;
+}
+
+int
+RROutputAddUserMode (RROutputPtr output,
+ RRModePtr mode)
+{
+ int m;
+ ScreenPtr pScreen = output->pScreen;
+ rrScrPriv(pScreen);
+ RRModePtr *newModes;
+
+ /* Check to see if this mode is already listed for this output */
+ for (m = 0; m < output->numModes + output->numUserModes; m++)
+ {
+ RRModePtr e = (m < output->numModes ?
+ output->modes[m] :
+ output->userModes[m - output->numModes]);
+ if (mode == e)
+ return Success;
+ }
+
+ /* Check with the DDX to see if this mode is OK */
+ if (pScrPriv->rrOutputValidateMode)
+ if (!pScrPriv->rrOutputValidateMode (pScreen, output, mode))
+ return BadMatch;
+
+ if (output->userModes)
+ newModes = realloc(output->userModes,
+ (output->numUserModes + 1) * sizeof (RRModePtr));
+ else
+ newModes = malloc(sizeof (RRModePtr));
+ if (!newModes)
+ return BadAlloc;
+
+ output->userModes = newModes;
+ output->userModes[output->numUserModes++] = mode;
+ ++mode->refcnt;
+ RROutputChanged (output, TRUE);
+ RRTellChanged (pScreen);
+ return Success;
+}
+
+int
+RROutputDeleteUserMode (RROutputPtr output,
+ RRModePtr mode)
+{
+ int m;
+
+ /* Find this mode in the user mode list */
+ for (m = 0; m < output->numUserModes; m++)
+ {
+ RRModePtr e = output->userModes[m];
+
+ if (mode == e)
+ break;
+ }
+ /* Not there, access error */
+ if (m == output->numUserModes)
+ return BadAccess;
+
+ /* make sure the mode isn't active for this output */
+ if (output->crtc && output->crtc->mode == mode)
+ return BadMatch;
+
+ memmove (output->userModes + m, output->userModes + m + 1,
+ (output->numUserModes - m - 1) * sizeof (RRModePtr));
+ output->numUserModes--;
+ RRModeDestroy (mode);
+ return Success;
+}
+
+Bool
+RROutputSetCrtcs (RROutputPtr output,
+ RRCrtcPtr *crtcs,
+ int numCrtcs)
+{
+ RRCrtcPtr *newCrtcs;
+ int i;
+
+ if (numCrtcs == output->numCrtcs)
+ {
+ for (i = 0; i < numCrtcs; i++)
+ if (output->crtcs[i] != crtcs[i])
+ break;
+ if (i == numCrtcs)
+ return TRUE;
+ }
+ if (numCrtcs)
+ {
+ newCrtcs = malloc(numCrtcs * sizeof (RRCrtcPtr));
+ if (!newCrtcs)
+ return FALSE;
+ }
+ else
+ newCrtcs = NULL;
+ if (output->crtcs)
+ free(output->crtcs);
+ memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr));
+ output->crtcs = newCrtcs;
+ output->numCrtcs = numCrtcs;
+ RROutputChanged (output, TRUE);
+ return TRUE;
+}
+
+Bool
+RROutputSetConnection (RROutputPtr output,
+ CARD8 connection)
+{
+ if (output->connection == connection)
+ return TRUE;
+ output->connection = connection;
+ RROutputChanged (output, TRUE);
+ return TRUE;
+}
+
+Bool
+RROutputSetSubpixelOrder (RROutputPtr output,
+ int subpixelOrder)
+{
+ if (output->subpixelOrder == subpixelOrder)
+ return TRUE;
+
+ output->subpixelOrder = subpixelOrder;
+ RROutputChanged (output, FALSE);
+ return TRUE;
+}
+
+Bool
+RROutputSetPhysicalSize (RROutputPtr output,
+ int mmWidth,
+ int mmHeight)
+{
+ if (output->mmWidth == mmWidth && output->mmHeight == mmHeight)
+ return TRUE;
+ output->mmWidth = mmWidth;
+ output->mmHeight = mmHeight;
+ RROutputChanged (output, FALSE);
+ 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);
+}
+
+/*
+ * Destroy a Output at shutdown
+ */
+void
+RROutputDestroy (RROutputPtr output)
+{
+ FreeResource (output->id, 0);
+}
+
+static int
+RROutputDestroyResource (pointer value, XID pid)
+{
+ RROutputPtr output = (RROutputPtr) value;
+ ScreenPtr pScreen = output->pScreen;
+ int m;
+
+ if (pScreen)
+ {
+ rrScrPriv(pScreen);
+ int i;
+
+ if (pScrPriv->primaryOutput == output)
+ pScrPriv->primaryOutput = NULL;
+
+ for (i = 0; i < pScrPriv->numOutputs; i++)
+ {
+ if (pScrPriv->outputs[i] == output)
+ {
+ memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1,
+ (pScrPriv->numOutputs - (i + 1)) * sizeof (RROutputPtr));
+ --pScrPriv->numOutputs;
+ break;
+ }
+ }
+ }
+ if (output->modes)
+ {
+ for (m = 0; m < output->numModes; m++)
+ RRModeDestroy (output->modes[m]);
+ free(output->modes);
+ }
+
+ for (m = 0; m < output->numUserModes; m++)
+ RRModeDestroy (output->userModes[m]);
+ if (output->userModes)
+ free(output->userModes);
+
+ if (output->crtcs)
+ free(output->crtcs);
+ if (output->clones)
+ free(output->clones);
+ RRDeleteAllOutputProperties (output);
+ free(output);
+ return 1;
+}
+
+/*
+ * Initialize output type
+ */
+Bool
+RROutputInit (void)
+{
+ RROutputType = CreateNewResourceType (RROutputDestroyResource, "OUTPUT");
+ if (!RROutputType)
+ return FALSE;
+ return TRUE;
+}
+
+#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
+
+int
+ProcRRGetOutputInfo (ClientPtr client)
+{
+ REQUEST(xRRGetOutputInfoReq);
+ xRRGetOutputInfoReply rep;
+ RROutputPtr output;
+ CARD8 *extra;
+ unsigned long extraLen;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ RRCrtc *crtcs;
+ RRMode *modes;
+ RROutput *clones;
+ char *name;
+ int i, n;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ pScreen = output->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = bytes_to_int32(OutputInfoExtra);
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.crtc = output->crtc ? output->crtc->id : None;
+ rep.mmWidth = output->mmWidth;
+ rep.mmHeight = output->mmHeight;
+ rep.connection = output->connection;
+ rep.subpixelOrder = output->subpixelOrder;
+ rep.nCrtcs = output->numCrtcs;
+ rep.nModes = output->numModes + output->numUserModes;
+ rep.nPreferred = output->numPreferred;
+ rep.nClones = output->numClones;
+ rep.nameLength = output->nameLength;
+
+ extraLen = ((output->numCrtcs +
+ output->numModes + output->numUserModes +
+ output->numClones +
+ bytes_to_int32(rep.nameLength)) << 2);
+
+ if (extraLen)
+ {
+ rep.length += bytes_to_int32(extraLen);
+ extra = malloc(extraLen);
+ if (!extra)
+ return BadAlloc;
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *) extra;
+ modes = (RRMode *) (crtcs + output->numCrtcs);
+ clones = (RROutput *) (modes + output->numModes + output->numUserModes);
+ name = (char *) (clones + output->numClones);
+
+ for (i = 0; i < output->numCrtcs; i++)
+ {
+ crtcs[i] = output->crtcs[i]->id;
+ if (client->swapped)
+ swapl (&crtcs[i], n);
+ }
+ for (i = 0; i < output->numModes + output->numUserModes; i++)
+ {
+ if (i < output->numModes)
+ modes[i] = output->modes[i]->mode.id;
+ else
+ modes[i] = output->userModes[i - output->numModes]->mode.id;
+ if (client->swapped)
+ swapl (&modes[i], n);
+ }
+ for (i = 0; i < output->numClones; i++)
+ {
+ clones[i] = output->clones[i]->id;
+ if (client->swapped)
+ swapl (&clones[i], n);
+ }
+ memcpy (name, output->name, output->nameLength);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swapl(&rep.crtc, n);
+ swapl(&rep.mmWidth, n);
+ swapl(&rep.mmHeight, n);
+ swaps(&rep.nCrtcs, n);
+ swaps(&rep.nModes, n);
+ swaps(&rep.nClones, n);
+ swaps(&rep.nameLength, n);
+ }
+ WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep);
+ if (extraLen)
+ {
+ WriteToClient (client, extraLen, (char *) extra);
+ free(extra);
+ }
+
+ return Success;
+}
+
+static void
+RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv,
+ RROutputPtr output)
+{
+ if (pScrPriv->primaryOutput == output)
+ return;
+
+ /* clear the old primary */
+ if (pScrPriv->primaryOutput) {
+ RROutputChanged(pScrPriv->primaryOutput, 0);
+ pScrPriv->primaryOutput = NULL;
+ }
+
+ /* set the new primary */
+ if (output) {
+ pScrPriv->primaryOutput = output;
+ RROutputChanged(output, 0);
+ }
+
+ pScrPriv->layoutChanged = TRUE;
+
+ RRTellChanged(pScreen);
+}
+
+int
+ProcRRSetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRSetOutputPrimaryReq);
+ RROutputPtr output = NULL;
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->output) {
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ if (output->pScreen != pWin->drawable.pScreen) {
+ client->errorValue = stuff->window;
+ return BadMatch;
+ }
+ }
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
+
+ return Success;
+}
+
+int
+ProcRRGetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPrimaryReq);
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+ xRRGetOutputPrimaryReply rep;
+ RROutputPtr primary = NULL;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ if (pScrPriv)
+ primary = pScrPriv->primaryOutput;
+
+ memset(&rep, 0, sizeof(rep));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.output = primary ? primary->id : None;
+
+ if (client->swapped) {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.output, n);
+ }
+
+ WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), &rep);
+
+ return Success;
+}
|