aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2016-06-20 11:10:06 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2016-06-21 04:09:17 +0200
commitc2b1f489d7998c83af73c7cb25bbb2bc53f26094 (patch)
treef6f5ff5fe899c840ffe6623244070699c10a95fe /nx-X11/programs/Xserver
parent2e5b98986ffe9de86d7329304ead298c164340bf (diff)
downloadnx-libs-c2b1f489d7998c83af73c7cb25bbb2bc53f26094.tar.gz
nx-libs-c2b1f489d7998c83af73c7cb25bbb2bc53f26094.tar.bz2
nx-libs-c2b1f489d7998c83af73c7cb25bbb2bc53f26094.zip
Backport RANDR proto version 1.5 to nx-X11's Xserver.
Backported to X.org's /xorg/xserver Git hash level: a6b6e8ba026acedef6336b17adf06aebddd5f22f.
Diffstat (limited to 'nx-X11/programs/Xserver')
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Extensions.c114
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Imakefile7
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Screen.c2
-rw-r--r--nx-X11/programs/Xserver/randr/Imakefile21
-rw-r--r--nx-X11/programs/Xserver/randr/randr.c325
-rw-r--r--nx-X11/programs/Xserver/randr/randr.h67
-rw-r--r--nx-X11/programs/Xserver/randr/randrproto.h478
-rw-r--r--nx-X11/programs/Xserver/randr/randrstr.h673
-rw-r--r--nx-X11/programs/Xserver/randr/rrcrtc.c1298
-rw-r--r--nx-X11/programs/Xserver/randr/rrdispatch.c119
-rw-r--r--nx-X11/programs/Xserver/randr/rrinfo.c35
-rw-r--r--nx-X11/programs/Xserver/randr/rrmode.c106
-rw-r--r--nx-X11/programs/Xserver/randr/rrmonitor.c792
-rw-r--r--nx-X11/programs/Xserver/randr/rroutput.c308
-rw-r--r--nx-X11/programs/Xserver/randr/rrpointer.c73
-rw-r--r--nx-X11/programs/Xserver/randr/rrproperty.c387
-rw-r--r--nx-X11/programs/Xserver/randr/rrprovider.c484
-rw-r--r--nx-X11/programs/Xserver/randr/rrproviderproperty.c752
-rw-r--r--nx-X11/programs/Xserver/randr/rrscreen.c508
-rw-r--r--nx-X11/programs/Xserver/randr/rrsdispatch.c343
-rw-r--r--nx-X11/programs/Xserver/randr/rrtransform.c301
-rw-r--r--nx-X11/programs/Xserver/randr/rrtransform.h79
-rw-r--r--nx-X11/programs/Xserver/randr/rrxinerama.c227
23 files changed, 6548 insertions, 951 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
index dfa511448..494027927 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -35,6 +35,32 @@ static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width,
static int nxagentRandRInitSizes(ScreenPtr pScreen);
+#if RANDR_14_INTERFACE
+static Bool
+nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
+ PixmapPtr pPixmap,
+ Bool enable);
+#endif
+
+#if RANDR_13_INTERFACE
+static Bool
+nxagentRandROutputGetProperty(ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property);
+static Bool
+nxagentRandRGetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+static Bool
+nxagentRandRSetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+#endif
+
#if RANDR_12_INTERFACE
static Bool nxagentRandRCrtcSet (ScreenPtr pScreen, RRCrtcPtr crtc,
RRModePtr mode, int x, int y,
@@ -104,6 +130,29 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
pRandRScrPriv -> rrGetInfo = nxagentRandRGetInfo;
+ #if RANDR_15_INTERFACE
+ /* nothing to be assigned here, so far */
+ #endif
+
+ #if RANDR_14_INTERFACE
+ /* no pixmap sharing in nx-X11 */
+ pScreen->ReplaceScanoutPixmap = nxagentRandRReplaceScanoutPixmap;
+ pRandRScrPriv -> rrCrtcSetScanoutPixmap = NULL;
+
+ /* only fake provider support in nx-X11, so far */
+ pRandRScrPriv -> provider = RRProviderCreate(pScreen, "default", 7);
+ pRandRScrPriv -> rrProviderSetOutputSource = NULL;
+ pRandRScrPriv -> rrProviderSetOffloadSink;
+ pRandRScrPriv -> rrProviderGetProperty;
+ pRandRScrPriv -> rrProviderSetProperty;
+ #endif
+
+ #if RANDR_13_INTERFACE
+ pRandRScrPriv -> rrOutputGetProperty = nxagentRandROutputGetProperty;
+ pRandRScrPriv -> rrGetPanning = nxagentRandRGetPanning;
+ pRandRScrPriv -> rrSetPanning = nxagentRandRSetPanning;
+ #endif
+
#if RANDR_12_INTERFACE
pRandRScrPriv -> rrScreenSetSize = nxagentRandRScreenSetSize;
pRandRScrPriv -> rrCrtcSet = nxagentRandRCrtcSet;
@@ -114,13 +163,70 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
#endif
}
-void
-RRResetProc (ExtensionEntry *extEntry)
+#if RANDR_14_INTERFACE
+static Bool
+nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
+ PixmapPtr pPixmap,
+ Bool enable)
+{
+ /* FALSE means: not supported */
+#ifdef DEBUG
+ fprintf(stderr, "nxagentRandRReplaceScanoutPixmap: NX's RANDR does not support scan-out pixmaps.\n");
+#endif
+ return FALSE;
+}
+#endif
+
+#if RANDR_13_INTERFACE
+static Bool
+nxagentRandROutputGetProperty(ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property)
{
- fprintf(stderr, "RANDR going down - NX version\n");
+ /* FALSE means: no property required to be modified on the fly here */
+ return FALSE;
}
+static Bool
+nxagentRandRGetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ /* FALSE means: no, panning is not supported at the moment...
+ * Panning requires several modes to be available for
+ * the NX<n> output(s).
+ *
+ * FIXME: Add more modes per output than the current window size.
+ * At least when in fullscreen mode.
+ */
+#ifdef DEBUG
+ fprintf(stderr, "nxagentRandRGetPanning: RANDR Panning is currently not supported.\n");
+#endif
+ return FALSE;
+}
+static Bool
+nxagentRandRSetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ /* FALSE means: no, panning is not supported at the moment...
+ * Panning requires several modes to be available for
+ * the NX<n> output(s).
+ *
+ * FIXME: Add more modes per output than the current window size.
+ * At least when in fullscreen mode.
+ */
+#ifdef DEBUG
+ fprintf(stderr, "nxagentRandRSetPanning: RANDR Panning is currently not supported.\n");
+#endif
+ return FALSE;
+}
+#endif
#if RANDR_12_INTERFACE
/*
@@ -137,7 +243,7 @@ nxagentRandRCrtcSet (ScreenPtr pScreen,
int numOutputs,
RROutputPtr *outputs)
{
- return RRCrtcNotify(crtc, mode, x, y, rotation, numOutputs, outputs);
+ return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutputs, outputs);
}
#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
index e9cef5ae3..121a1c774 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -209,8 +209,11 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(NX_DEFINES) \
-DNXAGENT_ARTSD \
-DNXAGENT_RANDR_MODE_PREFIX \
-UNX_DEBUG_INPUT \
- -DRANDR_10_INTERFACE \
- -DRANDR_12_INTERFACE \
+ -DRANDR_10_INTERFACE=1 \
+ -DRANDR_12_INTERFACE=1 \
+ -DRANDR_13_INTERFACE=1 \
+ -DRANDR_14_INTERFACE=1 \
+ -DRANDR_15_INTERFACE=1 \
-DPANORAMIX \
-UDEBUG_TREE
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index a4b39a4fe..40b1e5222 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -3793,7 +3793,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen)
* do this here it will be done implicitely later and add mode(s) to
* our crtc(s)!
*/
- rrgetinfo = RRGetInfo(pScreen);
+ rrgetinfo = RRGetInfo(pScreen, FALSE);
fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned [%d]\n", rrgetinfo);
}
diff --git a/nx-X11/programs/Xserver/randr/Imakefile b/nx-X11/programs/Xserver/randr/Imakefile
index 312dfb438..8dc8de1b7 100644
--- a/nx-X11/programs/Xserver/randr/Imakefile
+++ b/nx-X11/programs/Xserver/randr/Imakefile
@@ -24,11 +24,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke
rrdispatch.c \
rrinfo.c \
rrmode.c \
+ rrmonitor.c \
rroutput.c \
rrpointer.c \
rrproperty.c \
+ rrprovider.c \
+ rrproviderproperty.c \
rrscreen.c \
rrsdispatch.c \
+ rrtransform.c \
rrxinerama.c \
$(NULL)
@@ -37,11 +41,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke
rrdispatch.o \
rrinfo.o \
rrmode.o \
+ rrmonitor.o \
rroutput.o \
rrpointer.o \
rrproperty.o \
+ rrprovider.o \
+ rrproviderproperty.o \
rrscreen.o \
rrsdispatch.o \
+ rrtransform.o \
rrxinerama.o \
$(NULL)
@@ -50,9 +58,20 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke
-I../render \
`pkg-config --cflags-only-I pixman-1`
+#if defined(BuildXinerama)
+ PNRX_DEFINES = -DXINERAMA -DPANORAMIX
+#endif
+
+#if defined(NXAgentServer)
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
- DEFINES = -DNXAGENT_SERVER
+ DEFINES = \
+ $(PNRX_DEFINES) \
+ $(NX_DEFINES) \
+ $(NULL)
NormalLibraryTarget(randr,$(OBJS))
NormalLibraryObjectRule()
diff --git a/nx-X11/programs/Xserver/randr/randr.c b/nx-X11/programs/Xserver/randr/randr.c
index 1cb7e5b77..b78a947c8 100644
--- a/nx-X11/programs/Xserver/randr/randr.c
+++ b/nx-X11/programs/Xserver/randr/randr.c
@@ -50,6 +50,10 @@
#include "randrstr.h"
+#ifndef NXAGENT_SERVER
+#include "extinit.h"
+#endif
+
/* From render.h */
#ifndef SubPixelUnknown
#define SubPixelUnknown 0
@@ -59,12 +63,12 @@
static int RRNScreens;
#define wrap(priv,real,mem,func) {\
- priv->mem = real->mem; \
- real->mem = func; \
+ ((ScreenPtr)priv)->mem = ((ScreenPtr)real)->mem; \
+ ((ScreenPtr)real)->mem = func; \
}
#define unwrap(priv,real,mem) {\
- real->mem = priv->mem; \
+ ((ScreenPtr)real)->mem = ((ScreenPtr)priv)->mem; \
}
static int ProcRRDispatch(ClientPtr pClient);
@@ -106,13 +110,12 @@ RRClientCallback(CallbackListPtr *list, void *closure, void *data)
}
}
-static void
-RRResetProc(ExtensionEntry * extEntry)
-{
-}
-
static Bool
-RRCloseScreen(int i, ScreenPtr pScreen)
+RRCloseScreen(
+#ifdef NXAGENT_SERVER
+ int i,
+#endif
+ ScreenPtr pScreen)
{
rrScrPriv(pScreen);
int j;
@@ -123,6 +126,11 @@ RRCloseScreen(int i, ScreenPtr pScreen)
for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
RROutputDestroy(pScrPriv->outputs[j]);
+ if (pScrPriv->provider)
+ RRProviderDestroy(pScrPriv->provider);
+
+ RRMonitorClose(pScreen);
+
xfree(pScrPriv->crtcs);
xfree(pScrPriv->outputs);
xfree(pScrPriv);
@@ -142,11 +150,11 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent * from,
cpswapl(from->root, to->root);
cpswapl(from->window, to->window);
cpswaps(from->sizeID, to->sizeID);
+ cpswaps(from->subpixelOrder, to->subpixelOrder);
cpswaps(from->widthInPixels, to->widthInPixels);
cpswaps(from->heightInPixels, to->heightInPixels);
cpswaps(from->widthInMillimeters, to->widthInMillimeters);
cpswaps(from->heightInMillimeters, to->heightInMillimeters);
- cpswaps(from->subpixelOrder, to->subpixelOrder);
}
static void
@@ -160,8 +168,8 @@ SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent * from,
cpswapl(from->window, to->window);
cpswapl(from->crtc, to->crtc);
cpswapl(from->mode, to->mode);
- cpswapl(from->window, to->window);
cpswaps(from->rotation, to->rotation);
+ /* pad1 */
cpswaps(from->x, to->x);
cpswaps(from->y, to->y);
cpswaps(from->width, to->width);
@@ -182,6 +190,8 @@ SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent * from,
cpswapl(from->crtc, to->crtc);
cpswapl(from->mode, to->mode);
cpswaps(from->rotation, to->rotation);
+ to->connection = from->connection;
+ to->subpixelOrder = from->subpixelOrder;
}
static void
@@ -195,6 +205,52 @@ SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent * from,
cpswapl(from->output, to->output);
cpswapl(from->atom, to->atom);
cpswapl(from->timestamp, to->timestamp);
+ to->state = from->state;
+ /* pad1 */
+ /* pad2 */
+ /* pad3 */
+ /* pad4 */
+}
+
+static void
+SRRProviderChangeNotifyEvent(xRRProviderChangeNotifyEvent * from,
+ xRRProviderChangeNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->window, to->window);
+ cpswapl(from->provider, to->provider);
+}
+
+static void
+SRRProviderPropertyNotifyEvent(xRRProviderPropertyNotifyEvent * from,
+ xRRProviderPropertyNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->window, to->window);
+ cpswapl(from->provider, to->provider);
+ cpswapl(from->atom, to->atom);
+ cpswapl(from->timestamp, to->timestamp);
+ to->state = from->state;
+ /* pad1 */
+ /* pad2 */
+ /* pad3 */
+ /* pad4 */
+}
+
+static void
+SRRResourceChangeNotifyEvent(xRRResourceChangeNotifyEvent * from,
+ xRRResourceChangeNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->window, to->window);
}
static void
@@ -213,6 +269,17 @@ SRRNotifyEvent(xEvent *from, xEvent *to)
SRROutputPropertyNotifyEvent((xRROutputPropertyNotifyEvent *) from,
(xRROutputPropertyNotifyEvent *) to);
break;
+ case RRNotify_ProviderChange:
+ SRRProviderChangeNotifyEvent((xRRProviderChangeNotifyEvent *) from,
+ (xRRProviderChangeNotifyEvent *) to);
+ break;
+ case RRNotify_ProviderProperty:
+ SRRProviderPropertyNotifyEvent((xRRProviderPropertyNotifyEvent *) from,
+ (xRRProviderPropertyNotifyEvent *) to);
+ break;
+ case RRNotify_ResourceChange:
+ SRRResourceChangeNotifyEvent((xRRResourceChangeNotifyEvent *) from,
+ (xRRResourceChangeNotifyEvent *) to);
default:
break;
}
@@ -234,8 +301,15 @@ RRInit(void)
return FALSE;
if (!RROutputInit())
return FALSE;
+ if (!RRProviderInit())
+ return FALSE;
RRGeneration = serverGeneration;
}
+#ifndef NXAGENT_SERVER
+ if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+#endif /* !defined(NXAGENT_SERVER) */
+
return TRUE;
}
@@ -291,11 +365,15 @@ RRScreenInit(ScreenPtr pScreen)
wrap(pScrPriv, pScreen, CloseScreen, RRCloseScreen);
+ pScreen->ConstrainCursorHarder = RRConstrainCursorHarder;
+ pScreen->ReplaceScanoutPixmap = RRReplaceScanoutPixmap;
pScrPriv->numOutputs = 0;
pScrPriv->outputs = NULL;
pScrPriv->numCrtcs = 0;
pScrPriv->crtcs = NULL;
+ RRMonitorInit(pScreen);
+
RRNScreens += 1; /* keep count of screens that implement randr */
return TRUE;
}
@@ -309,7 +387,13 @@ RRFreeClient(void *data, XID id)
pRREvent = (RREventPtr) data;
pWin = pRREvent->window;
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixDestroyAccess);
+#else /* !defined(NXAGENT_SERVER) */
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+
if (pHead) {
pPrev = 0;
for (pCur = *pHead; pCur && pCur != pRREvent; pCur = pCur->next)
@@ -349,29 +433,38 @@ RRExtensionInit(void)
return;
#ifndef NXAGENT_SERVER
- if (!dixRequestPrivate(RRClientPrivateKey,
- sizeof(RRClientRec) +
- screenInfo.numScreens * sizeof(RRTimesRec)))
+ if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT,
+ sizeof(RRClientRec) +
+ screenInfo.numScreens * sizeof(RRTimesRec)))
return;
-#else
+#else /* !defined(NXAGENT_SERVER) */
RRClientPrivateIndex = AllocateClientPrivateIndex();
if (!AllocateClientPrivate(RRClientPrivateIndex,
sizeof(RRClientRec) +
screenInfo.numScreens * sizeof(RRTimesRec)))
return;
-#endif
+#endif /* !defined(NXAGENT_SERVER) */
+
if (!AddCallback(&ClientStateCallback, RRClientCallback, 0))
return;
- RRClientType = CreateNewResourceType(RRFreeClient);
+ RRClientType = CreateNewResourceType(RRFreeClient
+#ifndef NXAGENT_SERVER
+ , "RandRClient"
+#endif
+ );
if (!RRClientType)
return;
- RREventType = CreateNewResourceType(RRFreeEvents);
+ RREventType = CreateNewResourceType(RRFreeEvents
+#ifndef NXAGENT_SERVER
+ , "RandREvent"
+#endif
+ );
if (!RREventType)
return;
extEntry = AddExtension(RANDR_NAME, RRNumberEvents, RRNumberErrors,
ProcRRDispatch, SProcRRDispatch,
- RRResetProc, StandardMinorOpcode);
+ NULL, StandardMinorOpcode);
if (!extEntry)
return;
RRErrorBase = extEntry->errorBase;
@@ -380,11 +473,45 @@ RRExtensionInit(void)
SRRScreenChangeNotifyEvent;
EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr)
SRRNotifyEvent;
+
+ RRModeInitErrorValue();
+ RRCrtcInitErrorValue();
+ RROutputInitErrorValue();
+ RRProviderInitErrorValue();
#ifdef PANORAMIX
RRXineramaExtensionInit();
#endif
}
+void
+RRResourcesChanged(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ pScrPriv->resourcesChanged = TRUE;
+
+ RRSetChanged(pScreen);
+}
+
+static void
+RRDeliverResourceEvent(ClientPtr client, WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+
+ xRRResourceChangeNotifyEvent re = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_ResourceChange,
+#ifdef NXAGENT_SERVER
+ .sequenceNumber = client->sequence,
+#endif
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id
+ };
+
+ WriteEventsToClient(client, 1, (xEvent *) &re);
+}
+
static int
TellChanged(WindowPtr pWin, void *value)
{
@@ -392,10 +519,20 @@ TellChanged(WindowPtr pWin, void *value)
ClientPtr client;
ScreenPtr pScreen = pWin->drawable.pScreen;
+#ifndef NXAGENT_SERVER
+ ScreenPtr iter;
+ rrScrPrivPtr pSlaveScrPriv;
+#endif
+
rrScrPriv(pScreen);
int i;
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixReadAccess);
+#else /* !defined(NXAGENT_SERVER) */
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
if (!pHead)
return WT_WALKCHILDREN;
@@ -414,6 +551,18 @@ TellChanged(WindowPtr pWin, void *value)
if (crtc->changed)
RRDeliverCrtcEvent(client, pWin, crtc);
}
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pSlaveScrPriv->crtcs[i];
+
+ if (crtc->changed)
+ RRDeliverCrtcEvent(client, pWin, crtc);
+ }
+ }
+#endif
}
if (pRREvent->mask & RROutputChangeNotifyMask) {
@@ -423,36 +572,146 @@ TellChanged(WindowPtr pWin, void *value)
if (output->changed)
RRDeliverOutputEvent(client, pWin, output);
}
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++) {
+ RROutputPtr output = pSlaveScrPriv->outputs[i];
+
+ if (output->changed)
+ RRDeliverOutputEvent(client, pWin, output);
+ }
+ }
+#endif
+ }
+
+#ifndef NXAGENT_SERVER
+ if (pRREvent->mask & RRProviderChangeNotifyMask) {
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ }
+#endif
+
+ if (pRREvent->mask & RRResourceChangeNotifyMask) {
+ if (pScrPriv->resourcesChanged) {
+ RRDeliverResourceEvent(client, pWin);
+ }
}
}
return WT_WALKCHILDREN;
}
+void
+RRSetChanged(ScreenPtr pScreen)
+{
+#ifndef NXAGENT_SERVER
+ /* set changed bits on the master screen only */
+ ScreenPtr master;
+
+ rrScrPriv(pScreen);
+ rrScrPrivPtr mastersp;
+
+ if (pScreen->isGPU) {
+ master = pScreen->current_master;
+ if (!master)
+ return;
+ mastersp = rrGetScrPriv(master);
+ }
+ else
+ {
+ master = pScreen;
+ mastersp = pScrPriv;
+ }
+
+ mastersp->changed = TRUE;
+#else /* !defined(NXAGENT_SERVER) */
+ rrScrPriv(pScreen);
+ pScrPriv->changed = TRUE;
+#endif
+}
+
/*
* Something changed; send events and adjust pointer position
*/
void
RRTellChanged(ScreenPtr pScreen)
{
+ ScreenPtr master;
rrScrPriv(pScreen);
+ rrScrPrivPtr mastersp;
int i;
+#ifndef NXAGENT_SERVER
+ ScreenPtr iter;
+ rrScrPrivPtr pSlaveScrPriv;
+#endif
- if (pScrPriv->changed) {
- UpdateCurrentTime();
- if (pScrPriv->configChanged) {
- pScrPriv->lastConfigTime = currentTime;
- pScrPriv->configChanged = FALSE;
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ master = pScreen->current_master;
+ mastersp = rrGetScrPriv(master);
+ }
+ else
+#endif
+ {
+ master = pScreen;
+ mastersp = pScrPriv;
+ }
+
+ if (mastersp->changed) {
+ UpdateCurrentTimeIf();
+ if (mastersp->configChanged) {
+ mastersp->lastConfigTime = currentTime;
+ mastersp->configChanged = FALSE;
}
pScrPriv->changed = FALSE;
- WalkTree(pScreen, TellChanged, (void *) pScreen);
+ mastersp->changed = FALSE;
+
+ WalkTree(master, TellChanged, (void *) master);
+
+ mastersp->resourcesChanged = FALSE;
+
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) {
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &master->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++)
+ pSlaveScrPriv->outputs[i]->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++)
+ pSlaveScrPriv->crtcs[i]->changed = FALSE;
+ }
+ xorg_list_for_each_entry(iter, &master->offload_slave_list, offload_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ }
+ xorg_list_for_each_entry(iter, &master->unattached_list, unattached_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (mastersp->layoutChanged) {
pScrPriv->layoutChanged = FALSE;
- RRPointerScreenConfigured(pScreen);
- RRSendConfigNotify(pScreen);
+ RRPointerScreenConfigured(master);
+ RRSendConfigNotify(master);
}
}
}
@@ -468,6 +727,12 @@ RRFirstOutput(ScreenPtr pScreen)
RROutputPtr output;
int i, j;
+ if (!pScrPriv)
+ return NULL;
+
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
+ return pScrPriv->primaryOutput;
+
for (i = 0; i < pScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pScrPriv->crtcs[i];
@@ -500,6 +765,7 @@ ProcRRDispatch(ClientPtr client)
REQUEST(xReq);
if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
return BadRequest;
+ UpdateCurrentTimeIf();
return (*ProcRandrVector[stuff->data]) (client);
}
@@ -507,7 +773,8 @@ static int
SProcRRDispatch(ClientPtr client)
{
REQUEST(xReq);
- if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
+ if (stuff->data >= RRNumberRequests || !SProcRandrVector[stuff->data])
return BadRequest;
+ UpdateCurrentTimeIf();
return (*SProcRandrVector[stuff->data]) (client);
}
diff --git a/nx-X11/programs/Xserver/randr/randr.h b/nx-X11/programs/Xserver/randr/randr.h
index a3ef56c77..2018b372e 100644
--- a/nx-X11/programs/Xserver/randr/randr.h
+++ b/nx-X11/programs/Xserver/randr/randr.h
@@ -2,6 +2,7 @@
* Copyright © 2000 Compaq Computer Corporation
* Copyright © 2002 Hewlett Packard Company
* Copyright © 2006 Intel Corporation
+ * 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
@@ -39,11 +40,11 @@ typedef unsigned long XRandrModeFlags;
#define RANDR_NAME "RANDR"
#define RANDR_MAJOR 1
-#define RANDR_MINOR 2
+#define RANDR_MINOR 5
-#define RRNumberErrors 3
+#define RRNumberErrors 4
#define RRNumberEvents 2
-#define RRNumberRequests 25
+#define RRNumberRequests 45
#define X_RRQueryVersion 0
/* we skip 1 to make old clients fail pretty immediately */
@@ -77,12 +78,47 @@ typedef unsigned long XRandrModeFlags;
#define X_RRGetCrtcGamma 23
#define X_RRSetCrtcGamma 24
+/* V1.3 additions */
+#define X_RRGetScreenResourcesCurrent 25
+#define X_RRSetCrtcTransform 26
+#define X_RRGetCrtcTransform 27
+#define X_RRGetPanning 28
+#define X_RRSetPanning 29
+#define X_RRSetOutputPrimary 30
+#define X_RRGetOutputPrimary 31
+
+#define RRTransformUnit (1L << 0)
+#define RRTransformScaleUp (1L << 1)
+#define RRTransformScaleDown (1L << 2)
+#define RRTransformProjective (1L << 3)
+
+/* v1.4 */
+#define X_RRGetProviders 32
+#define X_RRGetProviderInfo 33
+#define X_RRSetProviderOffloadSink 34
+#define X_RRSetProviderOutputSource 35
+#define X_RRListProviderProperties 36
+#define X_RRQueryProviderProperty 37
+#define X_RRConfigureProviderProperty 38
+#define X_RRChangeProviderProperty 39
+#define X_RRDeleteProviderProperty 40
+#define X_RRGetProviderProperty 41
+
+/* v1.5 */
+#define X_RRGetMonitors 42
+#define X_RRSetMonitor 43
+#define X_RRDeleteMonitor 44
+
/* Event selection bits */
#define RRScreenChangeNotifyMask (1L << 0)
/* V1.2 additions */
#define RRCrtcChangeNotifyMask (1L << 1)
#define RROutputChangeNotifyMask (1L << 2)
#define RROutputPropertyNotifyMask (1L << 3)
+/* V1.4 additions */
+#define RRProviderChangeNotifyMask (1L << 4)
+#define RRProviderPropertyNotifyMask (1L << 5)
+#define RRResourceChangeNotifyMask (1L << 6)
/* Event codes */
#define RRScreenChangeNotify 0
@@ -92,7 +128,9 @@ typedef unsigned long XRandrModeFlags;
#define RRNotify_CrtcChange 0
#define RRNotify_OutputChange 1
#define RRNotify_OutputProperty 2
-
+#define RRNotify_ProviderChange 3
+#define RRNotify_ProviderProperty 4
+#define RRNotify_ResourceChange 5
/* used in the rotation field; rotation and reflection in 0.1 proto. */
#define RR_Rotate_0 1
#define RR_Rotate_90 2
@@ -133,9 +171,28 @@ typedef unsigned long XRandrModeFlags;
#define BadRROutput 0
#define BadRRCrtc 1
#define BadRRMode 2
+#define BadRRProvider 3
/* Conventional RandR output properties */
-#define RR_PROPERTY_RANDR_EDID "RANDR_EDID"
+#define RR_PROPERTY_BACKLIGHT "Backlight"
+#define RR_PROPERTY_RANDR_EDID "EDID"
+#define RR_PROPERTY_SIGNAL_FORMAT "SignalFormat"
+#define RR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties"
+#define RR_PROPERTY_CONNECTOR_TYPE "ConnectorType"
+#define RR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber"
+#define RR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList"
+#define RR_PROPERTY_CLONE_LIST "CloneList"
+#define RR_PROPERTY_BORDER "Border"
+#define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions"
+#define RR_PROPERTY_GUID "GUID"
+#define RR_PROPERTY_RANDR_TILE "TILE"
+
+/* roles this device can carry out */
+#define RR_Capability_None 0
+#define RR_Capability_SourceOutput 1
+#define RR_Capability_SinkOutput 2
+#define RR_Capability_SourceOffload 4
+#define RR_Capability_SinkOffload 8
#endif /* _RANDR_H_ */
diff --git a/nx-X11/programs/Xserver/randr/randrproto.h b/nx-X11/programs/Xserver/randr/randrproto.h
index be5b7adb5..116666ff5 100644
--- a/nx-X11/programs/Xserver/randr/randrproto.h
+++ b/nx-X11/programs/Xserver/randr/randrproto.h
@@ -2,6 +2,7 @@
* Copyright © 2000 Compaq Computer Corporation
* Copyright © 2002 Hewlett-Packard Company
* Copyright © 2006 Intel Corporation
+ * 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
@@ -30,8 +31,8 @@
#ifndef _XRANDRP_H_
#define _XRANDRP_H_
-/*#include <nx-X11/extensions/randr.h>*/
#include "randr.h"
+#include <nx-X11/extensions/renderproto.h>
#define Window CARD32
#define Drawable CARD32
@@ -47,7 +48,9 @@
#define RROutput CARD32
#define RRMode CARD32
#define RRCrtc CARD32
+#define RRProvider CARD32
#define RRModeFlags CARD32
+#define Atom CARD32
#define Rotation CARD16
#define SizeID CARD16
@@ -602,6 +605,296 @@ typedef struct {
#define sz_xRRSetCrtcGammaReq 12
/*
+ * Additions for V1.3
+ */
+
+typedef xRRGetScreenResourcesReq xRRGetScreenResourcesCurrentReq;
+
+#define sz_xRRGetScreenResourcesCurrentReq sz_xRRGetScreenResourcesReq
+
+typedef xRRGetScreenResourcesReply xRRGetScreenResourcesCurrentReply;
+
+#define sz_xRRGetScreenResourcesCurrentReply sz_xRRGetScreenResourcesReply
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRCrtc crtc B32;
+ xRenderTransform transform;
+ CARD16 nbytesFilter; /* number of bytes in filter name */
+ CARD16 pad B16;
+} xRRSetCrtcTransformReq;
+
+#define sz_xRRSetCrtcTransformReq 48
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRCrtc crtc B32;
+} xRRGetCrtcTransformReq;
+
+#define sz_xRRGetCrtcTransformReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ xRenderTransform pendingTransform;
+ BYTE hasTransforms;
+ CARD8 pad0;
+ CARD16 pad1 B16;
+ xRenderTransform currentTransform;
+ CARD32 pad2 B32;
+ CARD16 pendingNbytesFilter B16; /* number of bytes in filter name */
+ CARD16 pendingNparamsFilter B16; /* number of filter params */
+ CARD16 currentNbytesFilter B16; /* number of bytes in filter name */
+ CARD16 currentNparamsFilter B16; /* number of filter params */
+} xRRGetCrtcTransformReply;
+
+#define sz_xRRGetCrtcTransformReply 96
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ RROutput output B32;
+} xRRSetOutputPrimaryReq;
+
+#define sz_xRRSetOutputPrimaryReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+} xRRGetOutputPrimaryReq;
+
+#define sz_xRRGetOutputPrimaryReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ RROutput output B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xRRGetOutputPrimaryReply;
+
+#define sz_xRRGetOutputPrimaryReply 32
+
+/*
+ * Additions for V1.4
+ */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+} xRRGetProvidersReq;
+
+#define sz_xRRGetProvidersReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Time timestamp B32;
+ CARD16 nProviders;
+ CARD16 pad1 B16;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xRRGetProvidersReply;
+
+#define sz_xRRGetProvidersReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ Time configTimestamp B32;
+} xRRGetProviderInfoReq;
+
+#define sz_xRRGetProviderInfoReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Time timestamp B32;
+ CARD32 capabilities B32;
+ CARD16 nCrtcs B16;
+ CARD16 nOutputs B16;
+ CARD16 nAssociatedProviders B16;
+ CARD16 nameLength B16;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+} xRRGetProviderInfoReply;
+
+#define sz_xRRGetProviderInfoReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ RRProvider source_provider B32;
+ Time configTimestamp B32;
+} xRRSetProviderOutputSourceReq;
+
+#define sz_xRRSetProviderOutputSourceReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ RRProvider sink_provider B32;
+ Time configTimestamp B32;
+} xRRSetProviderOffloadSinkReq;
+
+#define sz_xRRSetProviderOffloadSinkReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+} xRRListProviderPropertiesReq;
+
+#define sz_xRRListProviderPropertiesReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad0;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 nAtoms B16;
+ CARD16 pad1 B16;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xRRListProviderPropertiesReply;
+
+#define sz_xRRListProviderPropertiesReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ Atom property B32;
+} xRRQueryProviderPropertyReq;
+
+#define sz_xRRQueryProviderPropertyReq 12
+
+typedef struct {
+ BYTE type;
+ BYTE pad0;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ BOOL pending;
+ BOOL range;
+ BOOL immutable;
+ BYTE pad1;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xRRQueryProviderPropertyReply;
+
+#define sz_xRRQueryProviderPropertyReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ Atom property B32;
+ BOOL pending;
+ BOOL range;
+ CARD16 pad B16;
+} xRRConfigureProviderPropertyReq;
+
+#define sz_xRRConfigureProviderPropertyReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ Atom property B32;
+ Atom type B32;
+ CARD8 format;
+ CARD8 mode;
+ CARD16 pad;
+ CARD32 nUnits B32;
+} xRRChangeProviderPropertyReq;
+
+#define sz_xRRChangeProviderPropertyReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ Atom property B32;
+} xRRDeleteProviderPropertyReq;
+
+#define sz_xRRDeleteProviderPropertyReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRProvider provider B32;
+ Atom property B32;
+ Atom type B32;
+ CARD32 longOffset B32;
+ CARD32 longLength B32;
+#ifdef __cplusplus
+ BOOL _delete;
+#else
+ BOOL delete;
+#endif
+ BOOL pending;
+ CARD16 pad1 B16;
+} xRRGetProviderPropertyReq;
+
+#define sz_xRRGetProviderPropertyReq 28
+
+typedef struct {
+ BYTE type;
+ CARD8 format;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Atom propertyType B32;
+ CARD32 bytesAfter B32;
+ CARD32 nItems B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+} xRRGetProviderPropertyReply;
+
+#define sz_xRRGetProviderPropertyReply 32
+
+/*
* event
*/
typedef struct {
@@ -644,8 +937,8 @@ typedef struct {
CARD8 type; /* always evBase + RRNotify */
CARD8 subCode; /* RRNotify_OutputChange */
CARD16 sequenceNumber B16;
- Time timestamp B32; /* time crtc was changed */
- Time configTimestamp B32; /* time crtc was changed */
+ Time timestamp B32; /* time output was changed */
+ Time configTimestamp B32; /* time config was changed */
Window window B32; /* window requesting notification */
RROutput output B32; /* affected output */
RRCrtc crtc B32; /* current crtc */
@@ -674,12 +967,190 @@ typedef struct {
#define sz_xRROutputPropertyNotifyEvent 32
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_ProviderChange */
+ CARD16 sequenceNumber B16;
+ Time timestamp B32; /* time provider was changed */
+ Window window B32; /* window requesting notification */
+ RRProvider provider B32; /* affected provider */
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+} xRRProviderChangeNotifyEvent;
+
+#define sz_xRRProviderChangeNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_ProviderProperty */
+ CARD16 sequenceNumber B16;
+ Window window B32; /* window requesting notification */
+ RRProvider provider B32; /* affected provider */
+ Atom atom B32; /* property name */
+ Time timestamp B32; /* time provider was changed */
+ CARD8 state; /* NewValue or Deleted */
+ CARD8 pad1;
+ CARD16 pad2 B16;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+} xRRProviderPropertyNotifyEvent;
+
+#define sz_xRRProviderPropertyNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_ResourceChange */
+ CARD16 sequenceNumber B16;
+ Time timestamp B32; /* time resource was changed */
+ Window window B32; /* window requesting notification */
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xRRResourceChangeNotifyEvent;
+
+#define sz_xRRResourceChangeNotifyEvent 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRCrtc crtc B32;
+} xRRGetPanningReq;
+
+#define sz_xRRGetPanningReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Time timestamp B32;
+ CARD16 left B16;
+ CARD16 top B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD16 track_left B16;
+ CARD16 track_top B16;
+ CARD16 track_width B16;
+ CARD16 track_height B16;
+ INT16 border_left B16;
+ INT16 border_top B16;
+ INT16 border_right B16;
+ INT16 border_bottom B16;
+} xRRGetPanningReply;
+
+#define sz_xRRGetPanningReply 36
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ RRCrtc crtc B32;
+ Time timestamp B32;
+ CARD16 left B16;
+ CARD16 top B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD16 track_left B16;
+ CARD16 track_top B16;
+ CARD16 track_width B16;
+ CARD16 track_height B16;
+ INT16 border_left B16;
+ INT16 border_top B16;
+ INT16 border_right B16;
+ INT16 border_bottom B16;
+} xRRSetPanningReq;
+
+#define sz_xRRSetPanningReq 36
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Time newTimestamp B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xRRSetPanningReply;
+
+#define sz_xRRSetPanningReply 32
+
+typedef struct {
+ Atom name B32;
+ BOOL primary;
+ BOOL automatic;
+ CARD16 noutput B16;
+ INT16 x B16;
+ INT16 y B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD32 widthInMillimeters B32;
+ CARD32 heightInMillimeters B32;
+} xRRMonitorInfo;
+
+#define sz_xRRMonitorInfo 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ BOOL get_active;
+ CARD8 pad;
+ CARD16 pad2;
+} xRRGetMonitorsReq;
+
+#define sz_xRRGetMonitorsReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Time timestamp B32;
+ CARD32 nmonitors B32;
+ CARD32 noutputs B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+} xRRGetMonitorsReply;
+
+#define sz_xRRGetMonitorsReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ xRRMonitorInfo monitor;
+} xRRSetMonitorReq;
+
+#define sz_xRRSetMonitorReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ Atom name B32;
+} xRRDeleteMonitorReq;
+
+#define sz_xRRDeleteMonitorReq 12
+
#undef RRModeFlags
#undef RRCrtc
#undef RRMode
#undef RROutput
#undef RRMode
#undef RRCrtc
+#undef RRProvider
#undef Drawable
#undef Window
#undef Font
@@ -694,5 +1165,6 @@ typedef struct {
#undef Rotation
#undef SizeID
#undef SubpixelOrder
+#undef Atom
#endif /* _XRANDRP_H_ */
diff --git a/nx-X11/programs/Xserver/randr/randrstr.h b/nx-X11/programs/Xserver/randr/randrstr.h
index 8e9107c9f..1bd0b9535 100644
--- a/nx-X11/programs/Xserver/randr/randrstr.h
+++ b/nx-X11/programs/Xserver/randr/randrstr.h
@@ -2,6 +2,7 @@
* Copyright © 2000 Compaq Computer Corporation
* Copyright © 2002 Hewlett-Packard Company
* Copyright © 2006 Intel Corporation
+ * 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
@@ -32,6 +33,10 @@
#ifndef _RANDRSTR_H_
#define _RANDRSTR_H_
+#ifndef NXAGENT_SERVER
+#include "list.h"
+#endif
+
#include <nx-X11/X.h>
#include <nx-X11/Xproto.h>
#include "misc.h"
@@ -43,26 +48,26 @@
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
-#ifndef NXAGENT_SERVER
-#include <nx-X11/extensions/randr.h>
-#include <nx-X11/extensions/randrproto.h>
-#else
+#include "rrtransform.h"
#include "randr.h"
#include "randrproto.h"
-#endif
-#ifdef RENDER
#include <nx-X11/extensions/render.h> /* we share subpixel order information */
#include "picturestr.h"
-#endif
#include <nx-X11/Xfuncproto.h>
/* required for ABI compatibility for now */
#define RANDR_10_INTERFACE 1
#define RANDR_12_INTERFACE 1
+#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
+#define RANDR_15_INTERFACE 1
+#define RANDR_GET_CRTC_INTERFACE 1
+
+#define RANDR_INTERFACE_VERSION 0x0104
typedef XID RRMode;
typedef XID RROutput;
typedef XID RRCrtc;
+typedef XID RRProvider;
extern int RREventBase, RRErrorBase;
@@ -79,6 +84,8 @@ typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr;
typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
typedef struct _rrOutput RROutputRec, *RROutputPtr;
+typedef struct _rrProvider RRProviderRec, *RRProviderPtr;
+typedef struct _rrMonitor RRMonitorRec, *RRMonitorPtr;
struct _rrMode {
int refcnt;
@@ -120,6 +127,14 @@ struct _rrCrtc {
CARD16 *gammaBlue;
CARD16 *gammaGreen;
void *devPrivate;
+ Bool transforms;
+ RRTransformRec client_pending_transform;
+ RRTransformRec client_current_transform;
+ PictTransform transform;
+ struct pict_f_transform f_transform;
+ struct pict_f_transform f_inverse;
+
+ PixmapPtr scanout_pixmap;
};
struct _rrOutput {
@@ -147,6 +162,35 @@ struct _rrOutput {
void *devPrivate;
};
+struct _rrProvider {
+ RRProvider id;
+ ScreenPtr pScreen;
+ uint32_t capabilities;
+ char *name;
+ int nameLength;
+ RRPropertyPtr properties;
+ Bool pendingProperties;
+ Bool changed;
+ struct _rrProvider *offload_sink;
+ struct _rrProvider *output_source;
+};
+
+typedef struct _rrMonitorGeometry {
+ BoxRec box;
+ CARD32 mmWidth;
+ CARD32 mmHeight;
+} RRMonitorGeometryRec, *RRMonitorGeometryPtr;
+
+struct _rrMonitor {
+ Atom name;
+ ScreenPtr pScreen;
+ int numOutputs;
+ RROutput *outputs;
+ Bool primary;
+ Bool automatic;
+ RRMonitorGeometryRec geometry;
+};
+
#if RANDR_12_INTERFACE
typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
CARD16 width,
@@ -163,6 +207,8 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
+typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
+
typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
RROutputPtr output,
Atom property,
@@ -176,8 +222,41 @@ typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, RRModePtr mode);
#endif
+#if RANDR_13_INTERFACE
+typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen,
+ RROutputPtr output, Atom property);
+typedef Bool (*RRGetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea, INT16 *border);
+typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea, INT16 *border);
+
+#endif /* RANDR_13_INTERFACE */
+
+typedef Bool (*RRProviderGetPropertyProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ Atom property);
+typedef Bool (*RRProviderSetPropertyProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ Atom property,
+ RRPropertyValuePtr value);
+
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations);
-typedef Bool (*RRCloseScreenProcPtr) (int i, ScreenPtr pscreen);
+typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen);
+
+typedef Bool (*RRProviderSetOutputSourceProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ RRProviderPtr output_source);
+
+typedef Bool (*RRProviderSetOffloadSinkProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ RRProviderPtr offload_sink);
+
+typedef void (*RRProviderDestroyProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider);
/* These are for 1.0 compatibility */
@@ -202,6 +281,8 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
#endif
+typedef Bool (*RRCrtcSetScanoutPixmapProcPtr) (RRCrtcPtr crtc, PixmapPtr pixmap);
+
typedef struct _rrScrPriv {
/*
* 'public' part of the structure; DDXen fill this in
@@ -215,10 +296,23 @@ typedef struct _rrScrPriv {
RRScreenSetSizeProcPtr rrScreenSetSize;
RRCrtcSetProcPtr rrCrtcSet;
RRCrtcSetGammaProcPtr rrCrtcSetGamma;
+ RRCrtcGetGammaProcPtr rrCrtcGetGamma;
RROutputSetPropertyProcPtr rrOutputSetProperty;
RROutputValidateModeProcPtr rrOutputValidateMode;
RRModeDestroyProcPtr rrModeDestroy;
#endif
+#if RANDR_13_INTERFACE
+ RROutputGetPropertyProcPtr rrOutputGetProperty;
+ RRGetPanningProcPtr rrGetPanning;
+ RRSetPanningProcPtr rrSetPanning;
+#endif
+ /* TODO #if RANDR_15_INTERFACE */
+ RRCrtcSetScanoutPixmapProcPtr rrCrtcSetScanoutPixmap;
+
+ RRProviderSetOutputSourceProcPtr rrProviderSetOutputSource;
+ RRProviderSetOffloadSinkProcPtr rrProviderSetOffloadSink;
+ RRProviderGetPropertyProcPtr rrProviderGetProperty;
+ RRProviderSetPropertyProcPtr rrProviderSetProperty;
/*
* Private part of the structure; not considered part of the ABI
@@ -230,6 +324,7 @@ typedef struct _rrScrPriv {
Bool changed; /* some config changed */
Bool configChanged; /* configuration changed */
Bool layoutChanged; /* screen layout changed */
+ Bool resourcesChanged; /* screen resources change */
CARD16 minWidth, minHeight;
CARD16 maxWidth, maxHeight;
@@ -238,6 +333,7 @@ typedef struct _rrScrPriv {
int numOutputs;
RROutputPtr *outputs;
+ RROutputPtr primaryOutput;
int numCrtcs;
RRCrtcPtr *crtcs;
@@ -259,9 +355,21 @@ typedef struct _rrScrPriv {
int rate;
int size;
#endif
+ Bool discontiguous;
+
+ RRProviderPtr provider;
+
+ RRProviderDestroyProcPtr rrProviderDestroy;
+
+ int numMonitors;
+ RRMonitorPtr *monitors;
+
} rrScrPrivRec, *rrScrPrivPtr;
#ifndef NXAGENT_SERVER
+extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
+
+#define rrPrivKey (&rrPrivKeyRec)
extern DevPrivateKey rrPrivKey;
#else
extern int rrPrivIndex;
@@ -269,17 +377,17 @@ extern int rrPrivIndex;
#ifndef NXAGENT_SERVER
-#define rrGetScrPriv(pScr) ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey))
-#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr)
+#define rrGetScrPriv(pScr) ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey))
+#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr)
#define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p)
-#else
+#else /* !defined(NXAGENT_SERVER) */
-#define rrGetScrPriv(pScr) ((rrScrPrivPtr) (pScr)->devPrivates[rrPrivIndex].ptr)
-#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr)
+#define rrGetScrPriv(pScr) ((rrScrPrivPtr) (pScr)->devPrivates[rrPrivIndex].ptr)
+#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr)
#define SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (void *) (p))
-#endif
+#endif /* !defined(NXAGENT_SERVER) */
/*
* each window has a list of clients requesting
@@ -317,43 +425,132 @@ extern DevPrivateKey RRClientPrivateKey;
#else
extern int RRClientPrivateIndex;
#endif
-extern RESTYPE RRCrtcType, RRModeType, RROutputType;
+
+extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType;
+
+#ifdef NXAGENT_SERVER
#define LookupOutput(client,id,a) ((RROutputPtr) \
- (SecurityLookupIDByType (client, id, \
- RROutputType, a)))
+ (SecurityLookupIDByType (client, id, \
+ RROutputType, a)))
#define LookupCrtc(client,id,a) ((RRCrtcPtr) \
- (SecurityLookupIDByType (client, id, \
- RRCrtcType, a)))
+ (SecurityLookupIDByType (client, id, \
+ RRCrtcType, a)))
#define LookupMode(client,id,a) ((RRModePtr) \
- (SecurityLookupIDByType (client, id, \
- RRModeType, a)))
-#ifndef NXAGENT_SERVER
-
-#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey))
-#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
-
-#else
-
-#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
-#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
+ (SecurityLookupIDByType (client, id, \
+ RRModeType, a)))
+#define LookupProvider(client,id,a) ((RRProviderPtr) \
+ (SecurityLookupIDByType (client, id, \
+ RRProviderType, a)))
#define DixUnknownAccess SecurityUnknownAccess
#define DixReadAccess SecurityReadAccess
#define DixWriteAccess SecurityWriteAccess
+#define DixSetAttrAccess SecurityWriteAccess
+#define DixUseAccess SecurityWriteAccess
#define DixDestroyAccess SecurityDestroyAccess
#endif
+#ifndef NXAGENT_SERVER
+
+#define RRClientPrivateKey (&RRClientPrivateKeyRec)
+#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey))
+
+#else /* !defined/NXAGENT_SERVER) */
+
+#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
+
+#endif /* !defined(NXAGENT_SERVER) */
+#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
+
/* Initialize the extension */
void
RRExtensionInit(void);
+#ifndef NXAGENT_SERVER
+#define VERIFY_RR_OUTPUT(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RROutputType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+
+#define VERIFY_RR_CRTC(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RRCrtcType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+
+#define VERIFY_RR_MODE(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RRModeType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+
+#define VERIFY_RR_PROVIDER(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RRProviderType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+#else /* !defined(NXAGENT_SERVER) */
+#define VERIFY_RR_OUTPUT(id, ptr, a)\
+ {\
+ ptr = LookupOutput(client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRROutput;\
+ }\
+ }
+
+#define VERIFY_RR_CRTC(id, ptr, a)\
+ {\
+ ptr = LookupCrtc (client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRRCrtc;\
+ }\
+ }
+
+#define VERIFY_RR_MODE(id, ptr, a)\
+ {\
+ ptr = LookupMode (client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRRMode;\
+ }\
+ }
+
+#define VERIFY_RR_PROVIDER(id, ptr, a)\
+ {\
+ ptr = LookupProvider (client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRRProvider;\
+ }\
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
#ifdef RANDR_12_INTERFACE
/*
* Set the range of sizes for the screen
*/
-void
+extern _X_EXPORT void
RRScreenSetSizeRange(ScreenPtr pScreen,
CARD16 minWidth,
@@ -366,13 +563,13 @@ RRScreenSetSizeRange(ScreenPtr pScreen,
* The driver is responsible for calling this whenever it has changed
* the size of the screen
*/
-void
+extern _X_EXPORT void
RRScreenSizeNotify(ScreenPtr pScreen);
/*
* Request that the screen be resized
*/
-Bool
+extern _X_EXPORT Bool
RRScreenSizeSet(ScreenPtr pScreen,
CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight);
@@ -380,85 +577,63 @@ RRScreenSizeSet(ScreenPtr pScreen,
/*
* Send ConfigureNotify event to root window when 'something' happens
*/
-void
+extern _X_EXPORT void
RRSendConfigNotify(ScreenPtr pScreen);
/*
* screen dispatch
*/
-int
+extern _X_EXPORT int
ProcRRGetScreenSizeRange(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRSetScreenSize(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRGetScreenResources(ClientPtr client);
-int
+extern _X_EXPORT int
+ ProcRRGetScreenResourcesCurrent(ClientPtr client);
+
+extern _X_EXPORT int
ProcRRSetScreenConfig(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRGetScreenInfo(ClientPtr client);
/*
* Deliver a ScreenNotify event
*/
-void
+extern _X_EXPORT void
RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen);
-/* mirandr.c */
-Bool
- miRandRInit(ScreenPtr pScreen);
-
-Bool
- miRRGetInfo(ScreenPtr pScreen, Rotation * rotations);
-
-Bool
- miRRGetScreenInfo(ScreenPtr pScreen);
-
-Bool
-
-miRRCrtcSet(ScreenPtr pScreen,
- RRCrtcPtr crtc,
- RRModePtr mode,
- int x,
- int y, Rotation rotation, int numOutput, RROutputPtr * outputs);
-
-Bool
-
-miRROutputSetProperty(ScreenPtr pScreen,
- RROutputPtr output,
- Atom property, RRPropertyValuePtr value);
-
-Bool
- miRROutputValidateMode(ScreenPtr pScreen, RROutputPtr output, RRModePtr mode);
-
-void
- miRRModeDestroy(ScreenPtr pScreen, RRModePtr mode);
+extern _X_EXPORT void
+ RRResourcesChanged(ScreenPtr pScreen);
/* randr.c */
+/* set a screen change on the primary screen */
+extern _X_EXPORT void
+ RRSetChanged(ScreenPtr pScreen);
+
/*
* Send all pending events
*/
-void
+extern _X_EXPORT void
RRTellChanged(ScreenPtr pScreen);
/*
* Poll the driver for changed information
*/
-Bool
- RRGetInfo(ScreenPtr pScreen);
+extern _X_EXPORT Bool
+ RRGetInfo(ScreenPtr pScreen, Bool force_query);
-Bool RRInit(void);
+extern _X_EXPORT Bool RRInit(void);
-Bool RRScreenInit(ScreenPtr pScreen);
+extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen);
-RROutputPtr RRFirstOutput(ScreenPtr pScreen);
+extern _X_EXPORT RROutputPtr RRFirstOutput(ScreenPtr pScreen);
-Rotation RRGetRotation(ScreenPtr pScreen);
-
-CARD16
+extern _X_EXPORT CARD16
RRVerticalRefresh(xRRModeInfo * mode);
#ifdef RANDR_10_INTERFACE
@@ -471,29 +646,24 @@ CARD16
* Then, register the specific size with the screen
*/
-RRScreenSizePtr
+extern _X_EXPORT RRScreenSizePtr
RRRegisterSize(ScreenPtr pScreen,
short width, short height, short mmWidth, short mmHeight);
-Bool RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate);
+extern _X_EXPORT Bool
+ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate);
/*
* Finally, set the current configuration of the screen
*/
-void
+extern _X_EXPORT void
+
RRSetCurrentConfig(ScreenPtr pScreen,
Rotation rotation, int rate, RRScreenSizePtr pSize);
-Bool RRScreenInit(ScreenPtr pScreen);
-
-Rotation RRGetRotation(ScreenPtr pScreen);
-
-int
-
-RRSetScreenConfig(ScreenPtr pScreen,
- Rotation rotation, int rate, RRScreenSizePtr pSize);
+extern _X_EXPORT Rotation RRGetRotation(ScreenPtr pScreen);
#endif
@@ -503,38 +673,46 @@ RRSetScreenConfig(ScreenPtr pScreen,
* Notify the CRTC of some change; layoutChanged indicates that
* some position or size element changed
*/
-void
+extern _X_EXPORT void
RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged);
/*
* Create a CRTC
*/
-RRCrtcPtr RRCrtcCreate(ScreenPtr pScreen, void *devPrivate);
+extern _X_EXPORT RRCrtcPtr RRCrtcCreate(ScreenPtr pScreen, void *devPrivate);
/*
* Set the allowed rotations on a CRTC
*/
-void
+extern _X_EXPORT void
RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations);
/*
+ * Set whether transforms are allowed on a CRTC
+ */
+extern _X_EXPORT void
+ RRCrtcSetTransformSupport(RRCrtcPtr crtc, Bool transforms);
+
+/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
*/
-Bool
+extern _X_EXPORT Bool
RRCrtcNotify(RRCrtcPtr crtc,
RRModePtr mode,
int x,
- int y, Rotation rotation, int numOutputs, RROutputPtr * outputs);
+ int y,
+ Rotation rotation,
+ RRTransformPtr transform, int numOutputs, RROutputPtr * outputs);
-void
+extern _X_EXPORT void
RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
/*
* Request that the Crtc be reconfigured
*/
-Bool
+extern _X_EXPORT Bool
RRCrtcSet(RRCrtcPtr crtc,
RRModePtr mode,
@@ -545,23 +723,31 @@ RRCrtcSet(RRCrtcPtr crtc,
* Request that the Crtc gamma be changed
*/
-Bool
+extern _X_EXPORT Bool
RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue);
/*
+ * Request current gamma back from the DDX (if possible).
+ * This includes gamma size.
+ */
+
+extern _X_EXPORT Bool
+ RRCrtcGammaGet(RRCrtcPtr crtc);
+
+/*
* Notify the extension that the Crtc gamma has been changed
* The driver calls this whenever it has changed the gamma values
* in the RRCrtcRec
*/
-Bool
+extern _X_EXPORT Bool
RRCrtcGammaNotify(RRCrtcPtr crtc);
/*
* Set the size of the gamma table at server startup time
*/
-Bool
+extern _X_EXPORT Bool
RRCrtcGammaSetSize(RRCrtcPtr crtc, int size);
/*
@@ -569,42 +755,99 @@ Bool
* taking into account the current mode and rotation
*/
-void
+extern _X_EXPORT void
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
/*
+ * Return crtc transform
+ */
+extern _X_EXPORT RRTransformPtr RRCrtcGetTransform(RRCrtcPtr crtc);
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+extern _X_EXPORT Bool
+ RRCrtcPendingTransform(RRCrtcPtr crtc);
+
+/*
* Destroy a Crtc at shutdown
*/
-void
+extern _X_EXPORT void
RRCrtcDestroy(RRCrtcPtr crtc);
/*
+ * Set the pending CRTC transformation
+ */
+
+extern _X_EXPORT int
+
+RRCrtcTransformSet(RRCrtcPtr crtc,
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse,
+ char *filter, int filter_len, xFixed * params, int nparams);
+
+/*
* Initialize crtc type
*/
-Bool
+extern _X_EXPORT Bool
RRCrtcInit(void);
/*
+ * Initialize crtc type error value
+ */
+extern _X_EXPORT void
+ RRCrtcInitErrorValue(void);
+
+/*
+ * Detach and free a scanout pixmap
+ */
+extern _X_EXPORT void
+ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc);
+
+extern _X_EXPORT Bool
+ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable);
+
+/*
* Crtc dispatch
*/
-int
+extern _X_EXPORT int
ProcRRGetCrtcInfo(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRSetCrtcConfig(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRGetCrtcGammaSize(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRGetCrtcGamma(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRSetCrtcGamma(ClientPtr client);
+extern _X_EXPORT int
+ ProcRRSetCrtcTransform(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetCrtcTransform(ClientPtr client);
+
+int
+ ProcRRGetPanning(ClientPtr client);
+
+int
+ ProcRRSetPanning(ClientPtr client);
+
+void
+ RRConstrainCursorHarder(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr, int, int *, int *);
+
/* rrdispatch.c */
-Bool
+extern _X_EXPORT Bool
RRClientKnowsRates(ClientPtr pClient);
/* rrmode.c */
@@ -612,39 +855,42 @@ Bool
* Find, and if necessary, create a mode
*/
-RRModePtr RRModeGet(xRRModeInfo * modeInfo, const char *name);
-
-void
- RRModePruneUnused(ScreenPtr pScreen);
+extern _X_EXPORT RRModePtr RRModeGet(xRRModeInfo * modeInfo, const char *name);
/*
* Destroy a mode.
*/
-void
+extern _X_EXPORT void
RRModeDestroy(RRModePtr mode);
/*
* Return a list of modes that are valid for some output in pScreen
*/
-RRModePtr *RRModesForScreen(ScreenPtr pScreen, int *num_ret);
+extern _X_EXPORT RRModePtr *RRModesForScreen(ScreenPtr pScreen, int *num_ret);
/*
* Initialize mode type
*/
-Bool
+extern _X_EXPORT Bool
RRModeInit(void);
-int
+/*
+ * Initialize mode type error value
+ */
+extern _X_EXPORT void
+ RRModeInitErrorValue(void);
+
+extern _X_EXPORT int
ProcRRCreateMode(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRDestroyMode(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRAddOutputMode(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRDeleteOutputMode(ClientPtr client);
/* rroutput.c */
@@ -655,116 +901,245 @@ int
* has changed, or whether the change was strictly internal
* (which crtc is in use)
*/
-void
+extern _X_EXPORT void
RROutputChanged(RROutputPtr output, Bool configChanged);
/*
* Create an output
*/
-RROutputPtr
+extern _X_EXPORT RROutputPtr
RROutputCreate(ScreenPtr pScreen,
const char *name, int nameLength, void *devPrivate);
/*
* Notify extension that output parameters have been changed
*/
-Bool
+extern _X_EXPORT Bool
RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones);
-Bool
+extern _X_EXPORT Bool
RROutputSetModes(RROutputPtr output,
RRModePtr * modes, int numModes, int numPreferred);
-int
+extern _X_EXPORT int
RROutputAddUserMode(RROutputPtr output, RRModePtr mode);
-int
+extern _X_EXPORT int
RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode);
-Bool
+extern _X_EXPORT Bool
RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs);
-Bool
+extern _X_EXPORT Bool
RROutputSetConnection(RROutputPtr output, CARD8 connection);
-Bool
+extern _X_EXPORT Bool
RROutputSetSubpixelOrder(RROutputPtr output, int subpixelOrder);
-Bool
+extern _X_EXPORT Bool
RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight);
-void
+extern _X_EXPORT void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
-void
+extern _X_EXPORT void
RROutputDestroy(RROutputPtr output);
-int
+extern _X_EXPORT int
ProcRRGetOutputInfo(ClientPtr client);
+extern _X_EXPORT int
+ ProcRRSetOutputPrimary(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetOutputPrimary(ClientPtr client);
+
/*
* Initialize output type
*/
-Bool
+extern _X_EXPORT Bool
RROutputInit(void);
+/*
+ * Initialize output type error value
+ */
+extern _X_EXPORT void
+ RROutputInitErrorValue(void);
+
/* rrpointer.c */
-void
+extern _X_EXPORT void
RRPointerMoved(ScreenPtr pScreen, int x, int y);
-void
+extern _X_EXPORT void
RRPointerScreenConfigured(ScreenPtr pScreen);
/* rrproperty.c */
-void
+extern _X_EXPORT void
RRDeleteAllOutputProperties(RROutputPtr output);
-RRPropertyValuePtr
+extern _X_EXPORT RRPropertyValuePtr
RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending);
-RRPropertyPtr RRQueryOutputProperty(RROutputPtr output, Atom property);
+extern _X_EXPORT RRPropertyPtr
+RRQueryOutputProperty(RROutputPtr output, Atom property);
-void
+extern _X_EXPORT void
RRDeleteOutputProperty(RROutputPtr output, Atom property);
-Bool
+extern _X_EXPORT Bool
RRPostPendingProperties(RROutputPtr output);
-int
+extern _X_EXPORT int
RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
void *value, Bool sendevent, Bool pending);
-int
+extern _X_EXPORT int
RRConfigureOutputProperty(RROutputPtr output, Atom property,
Bool pending, Bool range, Bool immutable,
int num_values, INT32 *values);
-int
+extern _X_EXPORT int
ProcRRChangeOutputProperty(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRGetOutputProperty(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRListOutputProperties(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRQueryOutputProperty(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRConfigureOutputProperty(ClientPtr client);
-int
+extern _X_EXPORT int
ProcRRDeleteOutputProperty(ClientPtr client);
+/* rrprovider.c */
+extern _X_EXPORT void
+ RRProviderInitErrorValue(void);
+
+extern _X_EXPORT int
+ ProcRRGetProviders(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetProviderInfo(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetProviderOutputSource(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetProviderOffloadSink(ClientPtr client);
+
+extern _X_EXPORT Bool
+ RRProviderInit(void);
+
+extern _X_EXPORT RRProviderPtr
+RRProviderCreate(ScreenPtr pScreen, const char *name, int nameLength);
+
+extern _X_EXPORT void
+ RRProviderDestroy(RRProviderPtr provider);
+
+extern _X_EXPORT void
+ RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities);
+
+extern _X_EXPORT Bool
+ RRProviderLookup(XID id, RRProviderPtr * provider_p);
+
+extern _X_EXPORT void
+
+RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider);
+
+/* rrproviderproperty.c */
+
+extern _X_EXPORT void
+ RRDeleteAllProviderProperties(RRProviderPtr provider);
+
+extern _X_EXPORT RRPropertyValuePtr
+RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending);
+
+extern _X_EXPORT RRPropertyPtr
+RRQueryProviderProperty(RRProviderPtr provider, Atom property);
+
+extern _X_EXPORT void
+ RRDeleteProviderProperty(RRProviderPtr provider, Atom property);
+
+extern _X_EXPORT int
+RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
+ int format, int mode, unsigned long len,
+ void *value, Bool sendevent, Bool pending);
+
+extern _X_EXPORT int
+RRConfigureProviderProperty(RRProviderPtr provider, Atom property,
+ Bool pending, Bool range, Bool immutable,
+ int num_values, INT32 *values);
+
+extern _X_EXPORT Bool
+ RRPostProviderPendingProperties(RRProviderPtr provider);
+
+extern _X_EXPORT int
+ ProcRRGetProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRListProviderProperties(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRQueryProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRConfigureProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRChangeProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRDeleteProviderProperty(ClientPtr client);
+
/* rrxinerama.c */
-void
+#ifdef XINERAMA
+extern _X_EXPORT void
RRXineramaExtensionInit(void);
+#endif
+
+void
+ RRMonitorInit(ScreenPtr screen);
+
+Bool
+
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr * monitors_ret, int *nmon_ret);
+
+int
+ RRMonitorCountList(ScreenPtr screen);
+
+void
+ RRMonitorFreeList(RRMonitorPtr monitors, int nmon);
+
+void
+ RRMonitorClose(ScreenPtr screen);
+
+RRMonitorPtr
+RRMonitorAlloc(int noutput);
+
+int
+ RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor);
+
+void
+ RRMonitorFree(RRMonitorPtr monitor);
+
+int
+ ProcRRGetMonitors(ClientPtr client);
+
+int
+ ProcRRSetMonitor(ClientPtr client);
+
+int
+ ProcRRDeleteMonitor(ClientPtr client);
#endif /* _RANDRSTR_H_ */
diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c
index 76b4c64f9..d69b5ec08 100644
--- a/nx-X11/programs/Xserver/randr/rrcrtc.c
+++ b/nx-X11/programs/Xserver/randr/rrcrtc.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2006 Keith Packard
+ * Copyright 2010 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
@@ -39,7 +40,7 @@
#include "randrstr.h"
#include "swaprep.h"
-#include "registry.h"
+#include "mipointer.h"
RESTYPE RRCrtcType;
@@ -55,7 +56,7 @@ RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged)
if (pScreen) {
rrScrPriv(pScreen);
- pScrPriv->changed = TRUE;
+ RRSetChanged(pScreen);
/*
* Send ConfigureNotify on any layout change
*/
@@ -81,8 +82,13 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
/* make space for the crtc pointer */
if (pScrPriv->numCrtcs)
+#ifndef NXAGENT_SERVER
+ crtcs = reallocarray(pScrPriv->crtcs,
+ pScrPriv->numCrtcs + 1, sizeof(RRCrtcPtr));
+#else /* !defined(NXAGENT_SERVER) */
crtcs = xrealloc(pScrPriv->crtcs,
(pScrPriv->numCrtcs + 1) * sizeof(RRCrtcPtr));
+#endif /* !defined(NXAGENT_SERVER) */
else
crtcs = xalloc(sizeof(RRCrtcPtr));
if (!crtcs)
@@ -105,6 +111,11 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
crtc->changed = FALSE;
crtc->devPrivate = devPrivate;
+ RRTransformInit(&crtc->client_pending_transform);
+ RRTransformInit(&crtc->client_current_transform);
+ pixman_transform_init_identity(&crtc->transform);
+ pixman_f_transform_init_identity(&crtc->f_transform);
+ pixman_f_transform_init_identity(&crtc->f_inverse);
if (!AddResource(crtc->id, RRCrtcType, (void *) crtc))
return NULL;
@@ -113,6 +124,8 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
crtc->pScreen = pScreen;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
+ RRResourcesChanged(pScreen);
+
return crtc;
}
@@ -126,6 +139,15 @@ RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations)
}
/*
+ * Set whether transforms are allowed on a CRTC
+ */
+void
+RRCrtcSetTransformSupport(RRCrtcPtr crtc, Bool transforms)
+{
+ crtc->transforms = transforms;
+}
+
+/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
*/
@@ -133,7 +155,9 @@ Bool
RRCrtcNotify(RRCrtcPtr crtc,
RRModePtr mode,
int x,
- int y, Rotation rotation, int numOutputs, RROutputPtr * outputs)
+ int y,
+ Rotation rotation,
+ RRTransformPtr transform, int numOutputs, RROutputPtr * outputs)
{
int i, j;
@@ -174,16 +198,24 @@ RRCrtcNotify(RRCrtcPtr crtc,
if (numOutputs) {
if (crtc->numOutputs)
+#ifndef NXAGENT_SERVER
+ newoutputs = reallocarray(crtc->outputs,
+ numOutputs, sizeof(RROutputPtr));
+#else /* !defined(NXAGENT_SERVER) */
newoutputs = xrealloc(crtc->outputs,
numOutputs * sizeof(RROutputPtr));
+#endif /* !defined(NXAGENT_SERVER) */
else
+#ifndef NXAGENT_SERVER
+ newoutputs = xallocarray(numOutputs, sizeof(RROutputPtr));
+#else /* !defined(NXAGENT_SERVER) */
newoutputs = xalloc(numOutputs * sizeof(RROutputPtr));
+#endif /* !defined(NXAGENT_SERVER) */
if (!newoutputs)
return FALSE;
}
else {
- if (crtc->outputs)
- xfree(crtc->outputs);
+ xfree(crtc->outputs);
newoutputs = NULL;
}
crtc->outputs = newoutputs;
@@ -216,6 +248,18 @@ RRCrtcNotify(RRCrtcPtr crtc,
crtc->rotation = rotation;
RRCrtcChanged(crtc, TRUE);
}
+ if (!RRTransformEqual(transform, &crtc->client_current_transform)) {
+ RRTransformCopy(&crtc->client_current_transform, transform);
+ RRCrtcChanged(crtc, TRUE);
+ }
+ if (crtc->changed && mode) {
+ RRTransformCompute(x, y,
+ mode->mode.width, mode->mode.height,
+ rotation,
+ &crtc->client_current_transform,
+ &crtc->transform, &crtc->f_transform,
+ &crtc->f_inverse);
+ }
return TRUE;
}
@@ -225,30 +269,24 @@ RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen);
- xRRCrtcChangeNotifyEvent ce;
RRModePtr mode = crtc->mode;
- ce.type = RRNotify + RREventBase;
- ce.subCode = RRNotify_CrtcChange;
- ce.sequenceNumber = client->sequence;
- ce.timestamp = pScrPriv->lastSetTime.milliseconds;
- ce.window = pWin->drawable.id;
- ce.crtc = crtc->id;
- ce.rotation = crtc->rotation;
- if (mode) {
- ce.mode = mode->mode.id;
- ce.x = crtc->x;
- ce.y = crtc->y;
- ce.width = mode->mode.width;
- ce.height = mode->mode.height;
- }
- else {
- ce.mode = None;
- ce.x = 0;
- ce.y = 0;
- ce.width = 0;
- ce.height = 0;
- }
+ xRRCrtcChangeNotifyEvent ce = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_CrtcChange,
+#ifdef NXAGENT_SERVER
+ .sequenceNumber = client->sequence,
+#endif
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id,
+ .crtc = crtc->id,
+ .mode = mode ? mode->mode.id : None,
+ .rotation = crtc->rotation,
+ .x = mode ? crtc->x : 0,
+ .y = mode ? crtc->y : 0,
+ .width = mode ? mode->mode.width : 0,
+ .height = mode ? mode->mode.height : 0
+ };
WriteEventsToClient(client, 1, (xEvent *) &ce);
}
@@ -269,6 +307,302 @@ RRCrtcPendingProperties(RRCrtcPtr crtc)
return FALSE;
}
+static void
+crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
+{
+ *left = crtc->x;
+ *top = crtc->y;
+
+ switch (crtc->rotation) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ default:
+ *right = crtc->x + crtc->mode->mode.width;
+ *bottom = crtc->y + crtc->mode->mode.height;
+ return;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ *right = crtc->x + crtc->mode->mode.height;
+ *bottom = crtc->y + crtc->mode->mode.width;
+ return;
+ }
+}
+
+/* overlapping counts as adjacent */
+static Bool
+crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
+{
+ /* left, right, top, bottom... */
+ int al, ar, at, ab;
+ int bl, br, bt, bb;
+ int cl, cr, ct, cb; /* the overlap, if any */
+
+ crtc_bounds(a, &al, &ar, &at, &ab);
+ crtc_bounds(b, &bl, &br, &bt, &bb);
+
+ cl = max(al, bl);
+ cr = min(ar, br);
+ ct = max(at, bt);
+ cb = min(ab, bb);
+
+ return (cl <= cr) && (ct <= cb);
+}
+
+/* Depth-first search and mark all CRTCs reachable from cur */
+static void
+mark_crtcs(rrScrPrivPtr pScrPriv, int *reachable, int cur)
+{
+ int i;
+
+ reachable[cur] = TRUE;
+ for (i = 0; i < pScrPriv->numCrtcs; ++i) {
+ if (reachable[i] || !pScrPriv->crtcs[i]->mode)
+ continue;
+ if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
+ mark_crtcs(pScrPriv, reachable, i);
+ }
+}
+
+static void
+RRComputeContiguity(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ Bool discontiguous = TRUE;
+ int i, n = pScrPriv->numCrtcs;
+
+ int *reachable = xcalloc(n, sizeof(int));
+
+ if (!reachable)
+ goto out;
+
+ /* Find first enabled CRTC and start search for reachable CRTCs from it */
+ for (i = 0; i < n; ++i) {
+ if (pScrPriv->crtcs[i]->mode) {
+ mark_crtcs(pScrPriv, reachable, i);
+ break;
+ }
+ }
+
+ /* Check that all enabled CRTCs were marked as reachable */
+ for (i = 0; i < n; ++i)
+ if (pScrPriv->crtcs[i]->mode && !reachable[i])
+ goto out;
+
+ discontiguous = FALSE;
+
+ out:
+ xfree(reachable);
+ pScrPriv->discontiguous = discontiguous;
+}
+
+static void
+rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr master = crtc->pScreen->current_master;
+
+ if (master && pPixmap->master_pixmap) {
+ PixmapPtr mscreenpix = master->GetScreenPixmap(master);
+
+ master->StopPixmapTracking(mscreenpix, pPixmap);
+ /*
+ * Unref the pixmap twice: once for the original reference, and once
+ * for the reference implicitly added by PixmapShareToSlave.
+ */
+ master->DestroyPixmap(pPixmap->master_pixmap);
+ master->DestroyPixmap(pPixmap->master_pixmap);
+ }
+#endif
+
+ crtc->pScreen->DestroyPixmap(pPixmap);
+}
+
+void
+RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
+{
+ rrScrPriv(crtc->pScreen);
+
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
+ if (crtc->scanout_pixmap) {
+ rrDestroySharedPixmap(crtc, crtc->scanout_pixmap);
+ }
+ crtc->scanout_pixmap = NULL;
+ RRCrtcChanged(crtc, TRUE);
+}
+
+#ifndef NXAGENT_SERVER
+static PixmapPtr
+rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master,
+ int width, int height, int depth,
+ int x, int y, Rotation rotation)
+{
+ Bool ret;
+ PixmapPtr mpix, spix;
+ rrScrPriv(crtc->pScreen);
+
+ mpix = master->CreatePixmap(master, width, height, depth,
+ CREATE_PIXMAP_USAGE_SHARED);
+ if (!mpix)
+ return NULL;
+
+ spix = PixmapShareToSlave(mpix, crtc->pScreen);
+ if (spix == NULL) {
+ master->DestroyPixmap(mpix);
+ return NULL;
+ }
+
+ ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
+ if (ret == FALSE) {
+ rrDestroySharedPixmap(crtc, spix);
+ ErrorF("randr: failed to set shadow slave pixmap\n");
+ return NULL;
+ }
+
+ return spix;
+}
+
+static Bool
+rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
+ int x, int y, Rotation rotation)
+{
+ ScreenPtr master = crtc->pScreen->current_master;
+ int depth;
+ PixmapPtr mscreenpix;
+ PixmapPtr spix;
+
+ /* create a pixmap on the master screen,
+ then get a shared handle for it
+ create a shared pixmap on the slave screen using the handle
+ set the master screen to do dirty updates to the shared pixmap
+ from the screen pixmap.
+ set slave screen to scanout shared linear pixmap
+ */
+
+ mscreenpix = master->GetScreenPixmap(master);
+ depth = mscreenpix->drawable.depth;
+
+ if (crtc->scanout_pixmap)
+ RRCrtcDetachScanoutPixmap(crtc);
+
+ if (width == 0 && height == 0) {
+ return TRUE;
+ }
+
+ spix = rrCreateSharedPixmap(crtc, master,
+ width, height, depth,
+ x, y, rotation);
+ if (spix == NULL) {
+ return FALSE;
+ }
+
+ crtc->scanout_pixmap = spix;
+
+ master->StartPixmapTracking(mscreenpix, spix, x, y, 0, 0, rotation);
+ return TRUE;
+}
+
+static void crtc_to_box(BoxPtr box, RRCrtcPtr crtc)
+{
+ box->x1 = crtc->x;
+ box->y1 = crtc->y;
+ switch (crtc->rotation) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ default:
+ box->x2 = crtc->x + crtc->mode->mode.width;
+ box->y2 = crtc->y + crtc->mode->mode.height;
+ break;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ box->x2 = crtc->x + crtc->mode->mode.height;
+ box->y2 = crtc->y + crtc->mode->mode.width;
+ break;
+ }
+}
+
+static Bool
+rrCheckPixmapBounding(ScreenPtr pScreen,
+ RRCrtcPtr rr_crtc, Rotation rotation,
+ int x, int y, int w, int h)
+{
+ RegionRec root_pixmap_region, total_region, new_crtc_region;
+ int c;
+ BoxRec newbox;
+ BoxPtr newsize;
+ ScreenPtr slave;
+ int new_width, new_height;
+ PixmapPtr screen_pixmap = pScreen->GetScreenPixmap(pScreen);
+ rrScrPriv(pScreen);
+
+ PixmapRegionInit(&root_pixmap_region, screen_pixmap);
+ RegionInit(&total_region, NULL, 0);
+
+ /* have to iterate all the crtcs of the attached gpu masters
+ and all their output slaves */
+ for (c = 0; c < pScrPriv->numCrtcs; c++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+
+ if (crtc == rr_crtc) {
+ newbox.x1 = x;
+ newbox.y1 = y;
+ if (rotation == RR_Rotate_90 ||
+ rotation == RR_Rotate_270) {
+ newbox.x2 = x + h;
+ newbox.y2 = y + w;
+ } else {
+ newbox.x2 = x + w;
+ newbox.y2 = y + h;
+ }
+ } else {
+ if (!crtc->mode)
+ continue;
+ crtc_to_box(&newbox, crtc);
+ }
+ RegionInit(&new_crtc_region, &newbox, 1);
+ RegionUnion(&total_region, &total_region, &new_crtc_region);
+ }
+
+ xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ rrScrPrivPtr slave_priv = rrGetScrPriv(slave);
+ for (c = 0; c < slave_priv->numCrtcs; c++) {
+ RRCrtcPtr slave_crtc = slave_priv->crtcs[c];
+
+ if (slave_crtc == rr_crtc) {
+ newbox.x1 = x;
+ newbox.y1 = y;
+ if (rotation == RR_Rotate_90 ||
+ rotation == RR_Rotate_270) {
+ newbox.x2 = x + h;
+ newbox.y2 = y + w;
+ } else {
+ newbox.x2 = x + w;
+ newbox.y2 = y + h;
+ }
+ }
+ else {
+ if (!slave_crtc->mode)
+ continue;
+ crtc_to_box(&newbox, slave_crtc);
+ }
+ RegionInit(&new_crtc_region, &newbox, 1);
+ RegionUnion(&total_region, &total_region, &new_crtc_region);
+ }
+ }
+
+ newsize = RegionExtents(&total_region);
+ new_width = newsize->x2 - newsize->x1;
+ new_height = newsize->y2 - newsize->y1;
+
+ if (new_width == screen_pixmap->drawable.width &&
+ new_height == screen_pixmap->drawable.height) {
+ } else {
+ pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
+ }
+
+ /* set shatters TODO */
+ return TRUE;
+}
+#endif /* !defined(NXAGENT_SERVER) */
+
/*
* Request that the Crtc be reconfigured
*/
@@ -280,9 +614,20 @@ RRCrtcSet(RRCrtcPtr crtc,
{
ScreenPtr pScreen = crtc->pScreen;
Bool ret = FALSE;
+ Bool recompute = TRUE;
+ Bool crtcChanged;
+ int o;
rrScrPriv(pScreen);
+ crtcChanged = FALSE;
+ for (o = 0; o < numOutputs; o++) {
+ if (outputs[o] && outputs[o]->crtc != crtc) {
+ crtcChanged = TRUE;
+ break;
+ }
+ }
+
/* See if nothing changed */
if (crtc->mode == mode &&
crtc->x == x &&
@@ -290,10 +635,31 @@ RRCrtcSet(RRCrtcPtr crtc,
crtc->rotation == rotation &&
crtc->numOutputs == numOutputs &&
!memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr)) &&
- !RRCrtcPendingProperties(crtc)) {
+ !RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc) &&
+ !crtcChanged) {
+ recompute = FALSE;
ret = TRUE;
}
else {
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ ScreenPtr master = pScreen->current_master;
+ int width = 0, height = 0;
+
+ if (mode) {
+ width = mode->mode.width;
+ height = mode->mode.height;
+ }
+ ret = rrCheckPixmapBounding(master, crtc,
+ rotation, x, y, width, height);
+ if (!ret)
+ return FALSE;
+
+ if (pScreen->current_master) {
+ ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation);
+ }
+ }
+#endif
#if RANDR_12_INTERFACE
if (pScrPriv->rrCrtcSet) {
ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
@@ -308,7 +674,7 @@ RRCrtcSet(RRCrtcPtr crtc,
RRScreenRate rate;
if (!mode) {
- RRCrtcNotify(crtc, NULL, x, y, rotation, 0, NULL);
+ RRCrtcNotify(crtc, NULL, x, y, rotation, NULL, 0, NULL);
ret = TRUE;
}
else {
@@ -332,7 +698,8 @@ RRCrtcSet(RRCrtcPtr crtc,
* Old 1.0 interface tied screen size to mode size
*/
if (ret) {
- RRCrtcNotify(crtc, mode, x, y, rotation, 1, outputs);
+ RRCrtcNotify(crtc, mode, x, y, rotation, NULL, 1,
+ outputs);
RRScreenSizeNotify(pScreen);
}
}
@@ -340,7 +707,6 @@ RRCrtcSet(RRCrtcPtr crtc,
#endif
}
if (ret) {
- int o;
RRTellChanged(pScreen);
@@ -348,10 +714,38 @@ RRCrtcSet(RRCrtcPtr crtc,
RRPostPendingProperties(outputs[o]);
}
}
+
+ if (recompute)
+ RRComputeContiguity(pScreen);
+
return ret;
}
/*
+ * Return crtc transform
+ */
+RRTransformPtr
+RRCrtcGetTransform(RRCrtcPtr crtc)
+{
+ RRTransformPtr transform = &crtc->client_pending_transform;
+
+ if (pixman_transform_is_identity(&transform->transform))
+ return NULL;
+ return transform;
+}
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+Bool
+RRCrtcPendingTransform(RRCrtcPtr crtc)
+{
+ return memcmp(&crtc->client_current_transform.transform,
+ &crtc->client_pending_transform.transform,
+ sizeof(PictTransform)) != 0;
+}
+
+/*
* Destroy a Crtc at shutdown
*/
void
@@ -378,9 +772,13 @@ RRCrtcDestroyResource(void *value, XID pid)
break;
}
}
+
+ RRResourcesChanged(pScreen);
}
- if (crtc->gammaRed)
- xfree(crtc->gammaRed);
+
+ if (crtc->scanout_pixmap)
+ RRCrtcDetachScanoutPixmap(crtc);
+ xfree(crtc->gammaRed);
if (crtc->mode)
RRModeDestroy(crtc->mode);
xfree(crtc);
@@ -414,6 +812,29 @@ RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue)
}
/*
+ * Request current gamma back from the DDX (if possible).
+ * This includes gamma size.
+ */
+Bool
+RRCrtcGammaGet(RRCrtcPtr crtc)
+{
+ Bool ret = TRUE;
+
+#if RANDR_12_INTERFACE
+ ScreenPtr pScreen = crtc->pScreen;
+#endif
+
+#if RANDR_12_INTERFACE
+ if (pScreen) {
+ rrScrPriv(pScreen);
+ if (pScrPriv->rrCrtcGetGamma)
+ ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc);
+ }
+#endif
+ return ret;
+}
+
+/*
* Notify the extension that the Crtc gamma has been changed
* The driver calls this whenever it has changed the gamma values
* in the RRCrtcRec
@@ -425,30 +846,35 @@ RRCrtcGammaNotify(RRCrtcPtr crtc)
return TRUE; /* not much going on here */
}
-/**
- * Returns the width/height that the crtc scans out from the framebuffer
- */
-void
-RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
+static void
+RRModeGetScanoutSize(RRModePtr mode, PictTransformPtr transform,
+ int *width, int *height)
{
- if (crtc->mode == NULL) {
+ BoxRec box;
+
+ if (mode == NULL) {
*width = 0;
*height = 0;
return;
}
- switch (crtc->rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- *width = crtc->mode->mode.width;
- *height = crtc->mode->mode.height;
- break;
- case RR_Rotate_90:
- case RR_Rotate_270:
- *width = crtc->mode->mode.height;
- *height = crtc->mode->mode.width;
- break;
- }
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = mode->mode.width;
+ box.y2 = mode->mode.height;
+
+ pixman_transform_bounds(transform, &box);
+ *width = box.x2 - box.x1;
+ *height = box.y2 - box.y1;
+}
+
+/**
+ * Returns the width/height that the crtc scans out from the framebuffer
+ */
+void
+RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
+{
+ RRModeGetScanoutSize(crtc->mode, &crtc->transform, width, height);
}
/*
@@ -463,14 +889,17 @@ RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
if (size == crtc->gammaSize)
return TRUE;
if (size) {
+#ifndef NXAGENT_SERVER
+ gamma = xallocarray(size, 3 * sizeof(CARD16));
+#else /* !defined(NXAGENT_SERVER) */
gamma = xalloc(size * 3 * sizeof(CARD16));
+#endif /* !defined(NXAGENT_SERVER) */
if (!gamma)
return FALSE;
}
else
gamma = NULL;
- if (crtc->gammaRed)
- xfree(crtc->gammaRed);
+ xfree(crtc->gammaRed);
crtc->gammaRed = gamma;
crtc->gammaGreen = gamma + size;
crtc->gammaBlue = gamma + size * 2;
@@ -479,18 +908,79 @@ RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
}
/*
+ * Set the pending CRTC transformation
+ */
+
+int
+RRCrtcTransformSet(RRCrtcPtr crtc,
+ PictTransformPtr transform,
+ struct pixman_f_transform *f_transform,
+ struct pixman_f_transform *f_inverse,
+ char *filter_name,
+ int filter_len, xFixed * params, int nparams)
+{
+ PictFilterPtr filter = NULL;
+ int width = 0, height = 0;
+
+ if (!crtc->transforms)
+ return BadValue;
+
+ if (filter_len) {
+ filter = PictureFindFilter(crtc->pScreen, filter_name, filter_len);
+ if (!filter)
+ return BadName;
+ if (filter->ValidateParams) {
+ if (!filter->ValidateParams(crtc->pScreen, filter->id,
+ params, nparams, &width, &height))
+ return BadMatch;
+ }
+ else {
+ width = filter->width;
+ height = filter->height;
+ }
+ }
+ else {
+ if (nparams)
+ return BadMatch;
+ }
+ if (!RRTransformSetFilter(&crtc->client_pending_transform,
+ filter, params, nparams, width, height))
+ return BadAlloc;
+
+ crtc->client_pending_transform.transform = *transform;
+ crtc->client_pending_transform.f_transform = *f_transform;
+ crtc->client_pending_transform.f_inverse = *f_inverse;
+ return Success;
+}
+
+/*
* Initialize crtc type
*/
Bool
RRCrtcInit(void)
{
- RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource);
+ RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource
+#ifndef NXAGENT_SERVER
+ , "CRTC"
+#endif
+ );
if (!RRCrtcType)
return FALSE;
- RegisterResourceName(RRCrtcType, "CRTC");
+
return TRUE;
}
+/*
+ * Initialize crtc type error value
+ */
+void
+RRCrtcInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc);
+#endif
+}
+
int
ProcRRGetCrtcInfo(ClientPtr client)
{
@@ -504,14 +994,13 @@ ProcRRGetCrtcInfo(ClientPtr client)
RRModePtr mode;
RROutput *outputs;
RROutput *possible;
- int i, j, k, n;
+ int i, j, k;
int width, height;
+ BoxRec panned_area;
+ int n;
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
- crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
-
- if (!crtc)
- return RRErrorBase + BadRRCrtc;
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
/* All crtcs must be associated with screens before client
* requests are processed
@@ -521,16 +1010,28 @@ ProcRRGetCrtcInfo(ClientPtr client)
mode = crtc->mode;
- rep.type = X_Reply;
- rep.status = RRSetConfigSuccess;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.timestamp = pScrPriv->lastSetTime.milliseconds;
- rep.x = crtc->x;
- rep.y = crtc->y;
- RRCrtcGetScanoutSize(crtc, &width, &height);
- rep.width = width;
- rep.height = height;
+ rep = (xRRGetCrtcInfoReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) {
+ rep.x = panned_area.x1;
+ rep.y = panned_area.y1;
+ rep.width = panned_area.x2 - panned_area.x1;
+ rep.height = panned_area.y2 - panned_area.y1;
+ }
+ else {
+ RRCrtcGetScanoutSize(crtc, &width, &height);
+ rep.x = crtc->x;
+ rep.y = crtc->y;
+ rep.width = width;
+ rep.height = height;
+ }
rep.mode = mode ? mode->mode.id : 0;
rep.rotation = crtc->rotation;
rep.rotations = crtc->rotations;
@@ -591,7 +1092,7 @@ ProcRRGetCrtcInfo(ClientPtr client)
xfree(extra);
}
- return client->noClientException;
+ return Success;
}
int
@@ -608,32 +1109,35 @@ ProcRRSetCrtcConfig(ClientPtr client)
RROutput *outputIds;
TimeStamp time;
Rotation rotation;
- int i, j;
+ int
+#ifndef NXAGENT_SERVER
+ ret,
+#endif
+ i, j;
+ CARD8 status;
+ int n;
REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
- numOutputs = (stuff->length - (SIZEOF(xRRSetCrtcConfigReq) >> 2));
+ numOutputs = (stuff->length - bytes_to_int32(SIZEOF(xRRSetCrtcConfigReq)));
+
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
- crtc = LookupIDByType(stuff->crtc, RRCrtcType);
- if (!crtc) {
- client->errorValue = stuff->crtc;
- return RRErrorBase + BadRRCrtc;
- }
if (stuff->mode == None) {
mode = NULL;
if (numOutputs > 0)
return BadMatch;
}
else {
- mode = LookupIDByType(stuff->mode, RRModeType);
- if (!mode) {
- client->errorValue = stuff->mode;
- return RRErrorBase + BadRRMode;
- }
+ VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess);
if (numOutputs == 0)
return BadMatch;
}
if (numOutputs) {
+#ifndef NXAGENT_SERVER
+ outputs = xallocarray(numOutputs, sizeof(RROutputPtr));
+#else /* !defined(NXAGENT_SERVER) */
outputs = xalloc(numOutputs * sizeof(RROutputPtr));
+#endif /* !defined(NXAGENT_SERVER) */
if (!outputs)
return BadAlloc;
}
@@ -642,6 +1146,15 @@ ProcRRSetCrtcConfig(ClientPtr client)
outputIds = (RROutput *) (stuff + 1);
for (i = 0; i < numOutputs; i++) {
+#ifndef NXAGENT_SERVER
+ ret = dixLookupResourceByType((void **) (outputs + i), outputIds[i],
+ RROutputType, client, DixSetAttrAccess);
+
+ if (ret != Success) {
+ xfree(outputs);
+ return ret;
+ }
+#else /* !defined(NXAGENT_SERVER) */
outputs[i] = (RROutputPtr) LookupIDByType(outputIds[i], RROutputType);
if (!outputs[i]) {
client->errorValue = outputIds[i];
@@ -649,13 +1162,13 @@ ProcRRSetCrtcConfig(ClientPtr client)
xfree(outputs);
return RRErrorBase + BadRROutput;
}
+#endif /* !defined(NXAGENT_SERVER) */
/* validate crtc for this output */
for (j = 0; j < outputs[i]->numCrtcs; j++)
if (outputs[i]->crtcs[j] == crtc)
break;
if (j == outputs[i]->numCrtcs) {
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
return BadMatch;
}
/* validate mode for this output */
@@ -667,8 +1180,7 @@ ProcRRSetCrtcConfig(ClientPtr client)
break;
}
if (j == outputs[i]->numModes + outputs[i]->numUserModes) {
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
return BadMatch;
}
}
@@ -684,8 +1196,7 @@ ProcRRSetCrtcConfig(ClientPtr client)
break;
}
if (k == outputs[i]->numClones) {
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
return BadMatch;
}
}
@@ -698,7 +1209,7 @@ ProcRRSetCrtcConfig(ClientPtr client)
if (!pScrPriv) {
time = currentTime;
- rep.status = RRSetConfigFailed;
+ status = RRSetConfigFailed;
goto sendReply;
}
@@ -719,8 +1230,7 @@ ProcRRSetCrtcConfig(ClientPtr client)
* Invalid rotation
*/
client->errorValue = stuff->rotation;
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
return BadValue;
}
@@ -730,8 +1240,7 @@ ProcRRSetCrtcConfig(ClientPtr client)
* requested rotation or reflection not supported by screen
*/
client->errorValue = stuff->rotation;
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
return BadMatch;
}
@@ -739,71 +1248,220 @@ ProcRRSetCrtcConfig(ClientPtr client)
/*
* Check screen size bounds if the DDX provides a 1.2 interface
* for setting screen size. Else, assume the CrtcSet sets
- * the size along with the mode
+ * the size along with the mode. If the driver supports transforms,
+ * then it must allow crtcs to display a subset of the screen, so
+ * only do this check for drivers without transform support.
*/
- if (pScrPriv->rrScreenSetSize) {
- int source_width = mode->mode.width;
- int source_height = mode->mode.height;
-
- if ((rotation & 0xf) == RR_Rotate_90 ||
- (rotation & 0xf) == RR_Rotate_270) {
- source_width = mode->mode.height;
- source_height = mode->mode.width;
+ if (pScrPriv->rrScreenSetSize && !crtc->transforms) {
+ int source_width;
+ int source_height;
+ PictTransform transform;
+ struct pixman_f_transform f_transform, f_inverse;
+ int width, height;
+
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ width = pScreen->current_master->width;
+ height = pScreen->current_master->height;
}
- if (stuff->x + source_width > pScreen->width) {
+ else
+#else /* !defined(NXAGENT_SERVER) */
+ {
+ width = pScreen->width;
+ height = pScreen->height;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
+ RRTransformCompute(stuff->x, stuff->y,
+ mode->mode.width, mode->mode.height,
+ rotation,
+ &crtc->client_pending_transform,
+ &transform, &f_transform, &f_inverse);
+
+ RRModeGetScanoutSize(mode, &transform, &source_width,
+ &source_height);
+ if (stuff->x + source_width > width) {
client->errorValue = stuff->x;
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
return BadValue;
}
- if (stuff->y + source_height > pScreen->height) {
+ if (stuff->y + source_height > height) {
client->errorValue = stuff->y;
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
return BadValue;
}
}
#endif
}
- /*
- * Make sure the requested set-time is not older than
- * the last set-time
- */
- if (CompareTimeStamps(time, pScrPriv->lastSetTime) < 0) {
- rep.status = RRSetConfigInvalidTime;
- goto sendReply;
- }
-
if (!RRCrtcSet(crtc, mode, stuff->x, stuff->y,
rotation, numOutputs, outputs)) {
- rep.status = RRSetConfigFailed;
+ status = RRSetConfigFailed;
goto sendReply;
}
- rep.status = RRSetConfigSuccess;
+ status = RRSetConfigSuccess;
pScrPriv->lastSetTime = time;
sendReply:
- if (outputs)
- xfree(outputs);
+ xfree(outputs);
+
+ rep = (xRRSetCrtcConfigReply) {
+ .type = X_Reply,
+ .status = status,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .newTimestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.newTimestamp, n);
+ }
+ WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *) &rep);
- rep.type = X_Reply;
- /* rep.status has already been filled in */
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+ return Success;
+}
+
+int
+ProcRRGetPanning(ClientPtr client)
+{
+ REQUEST(xRRGetPanningReq);
+ xRRGetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv)
+ return RRErrorBase + BadRRCrtc;
+
+ rep = (xRRGetPanningReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = 1,
+ .timestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(pScreen, crtc, &total, &tracking, border)) {
+ rep.left = total.x1;
+ rep.top = total.y1;
+ rep.width = total.x2 - total.x1;
+ rep.height = total.y2 - total.y1;
+ rep.track_left = tracking.x1;
+ rep.track_top = tracking.y1;
+ rep.track_width = tracking.x2 - tracking.x1;
+ rep.track_height = tracking.y2 - tracking.y1;
+ rep.border_left = border[0];
+ rep.border_top = border[1];
+ rep.border_right = border[2];
+ rep.border_bottom = border[3];
+ }
if (client->swapped) {
- int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swaps(&rep.left, n);
+ swaps(&rep.top, n);
+ swaps(&rep.width, n);
+ swaps(&rep.height, n);
+ swaps(&rep.track_left, n);
+ swaps(&rep.track_top, n);
+ swaps(&rep.track_width, n);
+ swaps(&rep.track_height, n);
+ swaps(&rep.border_left, n);
+ swaps(&rep.border_top, n);
+ swaps(&rep.border_right, n);
+ swaps(&rep.border_bottom, n);
+ }
+ WriteToClient(client, sizeof(xRRGetPanningReply), (char *) &rep);
+ return Success;
+}
+
+int
+ProcRRSetPanning(ClientPtr client)
+{
+ REQUEST(xRRSetPanningReq);
+ xRRSetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp time;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+ CARD8 status;
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv) {
+ time = currentTime;
+ status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+
+ if (!pScrPriv->rrGetPanning)
+ return RRErrorBase + BadRRCrtc;
+
+ total.x1 = stuff->left;
+ total.y1 = stuff->top;
+ total.x2 = total.x1 + stuff->width;
+ total.y2 = total.y1 + stuff->height;
+ tracking.x1 = stuff->track_left;
+ tracking.y1 = stuff->track_top;
+ tracking.x2 = tracking.x1 + stuff->track_width;
+ tracking.y2 = tracking.y1 + stuff->track_height;
+ border[0] = stuff->border_left;
+ border[1] = stuff->border_top;
+ border[2] = stuff->border_right;
+ border[3] = stuff->border_bottom;
+
+ if (!pScrPriv->rrSetPanning(pScreen, crtc, &total, &tracking, border))
+ return BadMatch;
+
+ pScrPriv->lastSetTime = time;
+ status = RRSetConfigSuccess;
+
+ sendReply:
+ rep = (xRRSetPanningReply) {
+ .type = X_Reply,
+ .status = status,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .newTimestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.newTimestamp, n);
}
- WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *) &rep);
-
- return client->noClientException;
+ WriteToClient(client, sizeof(xRRSetPanningReply), (char *) &rep);
+ return Success;
}
int
@@ -815,21 +1473,25 @@ ProcRRGetCrtcGammaSize(ClientPtr client)
int n;
REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
- crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
- if (!crtc)
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* Gamma retrieval failed, any better error? */
+ if (!RRCrtcGammaGet(crtc))
return RRErrorBase + BadRRCrtc;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = 0;
- reply.size = crtc->gammaSize;
+ reply = (xRRGetCrtcGammaSizeReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .size = crtc->gammaSize
+ };
if (client->swapped) {
swaps(&reply.sequenceNumber, n);
swapl(&reply.length, n);
swaps(&reply.size, n);
}
WriteToClient(client, sizeof(xRRGetCrtcGammaSizeReply), (char *) &reply);
- return client->noClientException;
+ return Success;
}
int
@@ -838,13 +1500,15 @@ ProcRRGetCrtcGamma(ClientPtr client)
REQUEST(xRRGetCrtcGammaReq);
xRRGetCrtcGammaReply reply;
RRCrtcPtr crtc;
- int n;
unsigned long len;
- char *extra;
+ char *extra = NULL;
+ int n;
REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
- crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
- if (!crtc)
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* Gamma retrieval failed, any better error? */
+ if (!RRCrtcGammaGet(crtc))
return RRErrorBase + BadRRCrtc;
len = crtc->gammaSize * 3 * 2;
@@ -855,10 +1519,12 @@ ProcRRGetCrtcGamma(ClientPtr client)
return BadAlloc;
}
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = (len + 3) >> 2;
- reply.size = crtc->gammaSize;
+ reply = (xRRGetCrtcGammaReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(len),
+ .size = crtc->gammaSize
+ };
if (client->swapped) {
swaps(&reply.sequenceNumber, n);
swapl(&reply.length, n);
@@ -871,7 +1537,7 @@ ProcRRGetCrtcGamma(ClientPtr client)
WriteSwappedDataToClient(client, len, extra);
xfree(extra);
}
- return client->noClientException;
+ return Success;
}
int
@@ -883,11 +1549,9 @@ ProcRRSetCrtcGamma(ClientPtr client)
CARD16 *red, *green, *blue;
REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
- crtc = LookupCrtc(client, stuff->crtc, DixWriteAccess);
- if (!crtc)
- return RRErrorBase + BadRRCrtc;
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
- len = client->req_len - (sizeof(xRRSetCrtcGammaReq) >> 2);
+ len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcGammaReq));
if (len < (stuff->size * 3 + 1) >> 1)
return BadLength;
@@ -902,3 +1566,335 @@ ProcRRSetCrtcGamma(ClientPtr client)
return Success;
}
+
+/* Version 1.3 additions */
+
+int
+ProcRRSetCrtcTransform(ClientPtr client)
+{
+ REQUEST(xRRSetCrtcTransformReq);
+ RRCrtcPtr crtc;
+ PictTransform transform;
+ struct pixman_f_transform f_transform, f_inverse;
+ char *filter;
+ int nbytes;
+ xFixed *params;
+ int nparams;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ PictTransform_from_xRenderTransform(&transform, &stuff->transform);
+ pixman_f_transform_from_pixman_transform(&f_transform, &transform);
+ if (!pixman_f_transform_invert(&f_inverse, &f_transform))
+ return BadMatch;
+
+ filter = (char *) (stuff + 1);
+ nbytes = stuff->nbytesFilter;
+ params = (xFixed *) (filter + pad_to_int32(nbytes));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ if (nparams < 0)
+ return BadLength;
+
+ return RRCrtcTransformSet(crtc, &transform, &f_transform, &f_inverse,
+ filter, nbytes, params, nparams);
+}
+
+#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32)
+
+static int
+transform_filter_length(RRTransformPtr transform)
+{
+ int nbytes, nparams;
+
+ if (transform->filter == NULL)
+ return 0;
+ nbytes = strlen(transform->filter->name);
+ nparams = transform->nparams;
+ return pad_to_int32(nbytes) + (nparams * sizeof(xFixed));
+}
+
+static int
+transform_filter_encode(ClientPtr client, char *output,
+ CARD16 *nbytesFilter,
+ CARD16 *nparamsFilter, RRTransformPtr transform)
+{
+ int nbytes, nparams;
+ int n;
+
+ if (transform->filter == NULL) {
+ *nbytesFilter = 0;
+ *nparamsFilter = 0;
+ return 0;
+ }
+ nbytes = strlen(transform->filter->name);
+ nparams = transform->nparams;
+ *nbytesFilter = nbytes;
+ *nparamsFilter = nparams;
+ memcpy(output, transform->filter->name, nbytes);
+ while ((nbytes & 3) != 0)
+ output[nbytes++] = 0;
+ memcpy(output + nbytes, transform->params, nparams * sizeof(xFixed));
+ if (client->swapped) {
+ swaps(nbytesFilter, n);
+ swaps(nparamsFilter, n);
+ SwapLongs((CARD32 *) (output + nbytes), nparams);
+ }
+ nbytes += nparams * sizeof(xFixed);
+ return nbytes;
+}
+
+static void
+transform_encode(ClientPtr client, xRenderTransform * wire,
+ PictTransform * pict)
+{
+ xRenderTransform_from_PictTransform(wire, pict);
+ if (client->swapped)
+ SwapLongs((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform)));
+}
+
+int
+ProcRRGetCrtcTransform(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcTransformReq);
+ xRRGetCrtcTransformReply *reply;
+ RRCrtcPtr crtc;
+ int nextra;
+ RRTransformPtr current, pending;
+ char *extra;
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ pending = &crtc->client_pending_transform;
+ current = &crtc->client_current_transform;
+
+ nextra = (transform_filter_length(pending) +
+ transform_filter_length(current));
+
+ reply = xcalloc(1, sizeof(xRRGetCrtcTransformReply) + nextra);
+ if (!reply)
+ return BadAlloc;
+
+ extra = (char *) (reply + 1);
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = bytes_to_int32(CrtcTransformExtra + nextra);
+
+ reply->hasTransforms = crtc->transforms;
+
+ transform_encode(client, &reply->pendingTransform, &pending->transform);
+ extra += transform_filter_encode(client, extra,
+ &reply->pendingNbytesFilter,
+ &reply->pendingNparamsFilter, pending);
+
+ transform_encode(client, &reply->currentTransform, &current->transform);
+ extra += transform_filter_encode(client, extra,
+ &reply->currentNbytesFilter,
+ &reply->currentNparamsFilter, current);
+
+ if (client->swapped) {
+ swaps(&reply->sequenceNumber, n);
+ swapl(&reply->length, n);
+ }
+ WriteToClient(client, sizeof(xRRGetCrtcTransformReply) + nextra,
+ (char *) reply);
+ xfree(reply);
+ return Success;
+}
+
+static Bool
+check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y)
+{
+ rrScrPriv(pScreen);
+ int i;
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ int left, right, top, bottom;
+
+ if (!crtc->mode)
+ continue;
+
+ crtc_bounds(crtc, &left, &right, &top, &bottom);
+
+ if ((*x >= left) && (*x < right) && (*y >= top) && (*y < bottom))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static Bool
+constrain_all_screen_crtcs(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr pScreen, int *x, int *y)
+{
+ rrScrPriv(pScreen);
+ int i;
+
+ /* if we're trying to escape, clamp to the CRTC we're coming from */
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+ int nx, ny;
+ int left, right, top, bottom;
+
+ if (!crtc->mode)
+ continue;
+
+ crtc_bounds(crtc, &left, &right, &top, &bottom);
+#ifndef NXAGENT_SERVER
+ miPointerGetPosition(pDev, &nx, &ny);
+#else /* !defined(NXAGENT_SERVER) */
+
+ miPointerPosition(&nx, &ny);
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom)) {
+ if (*x < left)
+ *x = left;
+ if (*x >= right)
+ *x = right - 1;
+ if (*y < top)
+ *y = top;
+ if (*y >= bottom)
+ *y = bottom - 1;
+
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+RRConstrainCursorHarder(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr pScreen, int mode, int *x,
+ int *y)
+{
+ rrScrPriv(pScreen);
+ Bool ret;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+
+ /* intentional dead space -> let it float */
+ if (pScrPriv->discontiguous)
+ return;
+
+ /* if we're moving inside a crtc, we're fine */
+ ret = check_all_screen_crtcs(pScreen, x, y);
+ if (ret == TRUE)
+ return;
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ ret = check_all_screen_crtcs(slave, x, y);
+ if (ret == TRUE)
+ return;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
+ /* if we're trying to escape, clamp to the CRTC we're coming from */
+ ret = constrain_all_screen_crtcs(
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ pScreen, x, y);
+ if (ret == TRUE)
+ return;
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ ret = constrain_all_screen_crtcs(pDev, slave, x, y);
+ if (ret == TRUE)
+ return;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+}
+
+Bool
+RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
+{
+ rrScrPriv(pDrawable->pScreen);
+ Bool ret = TRUE;
+ PixmapPtr *saved_scanout_pixmap;
+ int i;
+
+ saved_scanout_pixmap = xalloc(sizeof(PixmapPtr) * pScrPriv->numCrtcs);
+ if (saved_scanout_pixmap == NULL)
+ return FALSE;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+ Bool size_fits;
+
+ saved_scanout_pixmap[i] = crtc->scanout_pixmap;
+
+ if (!crtc->mode && enable)
+ continue;
+ if (!crtc->scanout_pixmap && !enable)
+ continue;
+
+ size_fits = (crtc->mode &&
+ crtc->x == pDrawable->x &&
+ crtc->y == pDrawable->y &&
+ crtc->mode->mode.width == pDrawable->width &&
+ crtc->mode->mode.height == pDrawable->height);
+
+ /* is the pixmap already set? */
+ if (crtc->scanout_pixmap == pPixmap) {
+ /* if its a disable then don't care about size */
+ if (enable == FALSE) {
+ /* set scanout to NULL */
+ crtc->scanout_pixmap = NULL;
+ }
+ else if (!size_fits) {
+ /* if the size no longer fits then drop off */
+ crtc->scanout_pixmap = NULL;
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
+
+ (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y,
+ crtc->rotation, crtc->numOutputs, crtc->outputs);
+ saved_scanout_pixmap[i] = crtc->scanout_pixmap;
+ ret = FALSE;
+ }
+ else {
+ /* if the size fits then we are already setup */
+ }
+ }
+ else {
+ if (!size_fits)
+ ret = FALSE;
+ else if (enable)
+ crtc->scanout_pixmap = pPixmap;
+ else
+ /* reject an attempt to disable someone else's scanout_pixmap */
+ ret = FALSE;
+ }
+ }
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ if (crtc->scanout_pixmap == saved_scanout_pixmap[i])
+ continue;
+
+ if (ret) {
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
+
+ (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode,
+ crtc->x, crtc->y, crtc->rotation,
+ crtc->numOutputs, crtc->outputs);
+ }
+ else
+ crtc->scanout_pixmap = saved_scanout_pixmap[i];
+ }
+ xfree(saved_scanout_pixmap);
+
+ return ret;
+}
diff --git a/nx-X11/programs/Xserver/randr/rrdispatch.c b/nx-X11/programs/Xserver/randr/rrdispatch.c
index a8fa6965f..a8ca35d16 100644
--- a/nx-X11/programs/Xserver/randr/rrdispatch.c
+++ b/nx-X11/programs/Xserver/randr/rrdispatch.c
@@ -21,48 +21,62 @@
*/
#include "randrstr.h"
-
-#define SERVER_RANDR_MAJOR 1
-#define SERVER_RANDR_MINOR 2
+#ifndef NXAGENT_SERVER
+#include "protocol-versions.h"
+#else
+#define SERVER_RANDR_MAJOR_VERSION 1
+#define SERVER_RANDR_MINOR_VERSION 5
+#endif
Bool
RRClientKnowsRates(ClientPtr pClient)
{
rrClientPriv(pClient);
- return (pRRClient->major_version > 1 ||
- (pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
+ return version_compare(pRRClient->major_version, pRRClient->minor_version,
+ 1, 1) >= 0;
}
static int
ProcRRQueryVersion(ClientPtr client)
{
- xRRQueryVersionReply rep;
- register int n;
+ int n;
+ xRRQueryVersionReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
REQUEST(xRRQueryVersionReq);
rrClientPriv(client);
REQUEST_SIZE_MATCH(xRRQueryVersionReq);
pRRClient->major_version = stuff->majorVersion;
pRRClient->minor_version = stuff->minorVersion;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- /*
- * Report the current version; the current
- * spec says they're all compatible after 1.0
- */
- rep.majorVersion = SERVER_RANDR_MAJOR;
- rep.minorVersion = SERVER_RANDR_MINOR;
+
+ if (version_compare(stuff->majorVersion, stuff->minorVersion,
+ SERVER_RANDR_MAJOR_VERSION,
+ SERVER_RANDR_MINOR_VERSION) < 0) {
+ rep.majorVersion = stuff->majorVersion;
+ rep.minorVersion = stuff->minorVersion;
+ }
+ else {
+ rep.majorVersion = SERVER_RANDR_MAJOR_VERSION;
+ rep.minorVersion = SERVER_RANDR_MINOR_VERSION;
+ }
+
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.majorVersion, n);
swapl(&rep.minorVersion, n);
}
+#ifndef NXAGENT_SERVER
+ WriteToClient(client, sizeof(xRRQueryVersionReply), &rep);
+#else
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *) &rep);
- return (client->noClientException);
+#endif
+ return Success;
}
static int
@@ -78,19 +92,30 @@ ProcRRSelectInput(ClientPtr client)
REQUEST_SIZE_MATCH(xRRSelectInputReq);
#ifndef NXAGENT_SERVER
- rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess);
rc = pWin ? Success : BadWindow;
#endif
if (rc != Success)
return rc;
- pHead = (RREventPtr *) SecurityLookupIDByType(client,
- pWin->drawable.id,
- RREventType, DixWriteAccess);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, client, DixWriteAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (rc != Success && rc != BadValue)
+ return rc;
if (stuff->enable & (RRScreenChangeNotifyMask |
- RRCrtcChangeNotifyMask | RROutputChangeNotifyMask)) {
+ RRCrtcChangeNotifyMask |
+ RROutputChangeNotifyMask |
+ RROutputPropertyNotifyMask |
+ RRProviderChangeNotifyMask |
+ RRProviderPropertyNotifyMask |
+ RRResourceChangeNotifyMask)) {
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen);
@@ -142,13 +167,37 @@ ProcRRSelectInput(ClientPtr client)
/*
* Now see if the client needs an event
*/
- if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) {
+ if (pScrPriv) {
pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
if (CompareTimeStamps(pTimes->setTime,
pScrPriv->lastSetTime) != 0 ||
CompareTimeStamps(pTimes->configTime,
pScrPriv->lastConfigTime) != 0) {
- RRDeliverScreenEvent(client, pWin, pScreen);
+ if (pRREvent->mask & RRScreenChangeNotifyMask) {
+ RRDeliverScreenEvent(client, pWin, pScreen);
+ }
+
+ if (pRREvent->mask & RRCrtcChangeNotifyMask) {
+ int i;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRDeliverCrtcEvent(client, pWin, pScrPriv->crtcs[i]);
+ }
+ }
+
+ if (pRREvent->mask & RROutputChangeNotifyMask) {
+ int i;
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ RRDeliverOutputEvent(client, pWin,
+ pScrPriv->outputs[i]);
+ }
+ }
+
+ /* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't
+ * say if there ought to be notifications of changes to output properties
+ * if those changes occurred before the time RRSelectInput is called.
+ */
}
}
}
@@ -209,4 +258,26 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
ProcRRGetCrtcGammaSize, /* 22 */
ProcRRGetCrtcGamma, /* 23 */
ProcRRSetCrtcGamma, /* 24 */
+/* V1.3 additions */
+ ProcRRGetScreenResourcesCurrent, /* 25 */
+ ProcRRSetCrtcTransform, /* 26 */
+ ProcRRGetCrtcTransform, /* 27 */
+ ProcRRGetPanning, /* 28 */
+ ProcRRSetPanning, /* 29 */
+ ProcRRSetOutputPrimary, /* 30 */
+ ProcRRGetOutputPrimary, /* 31 */
+/* V1.4 additions */
+ ProcRRGetProviders, /* 32 */
+ ProcRRGetProviderInfo, /* 33 */
+ ProcRRSetProviderOffloadSink, /* 34 */
+ ProcRRSetProviderOutputSource, /* 35 */
+ ProcRRListProviderProperties, /* 36 */
+ ProcRRQueryProviderProperty, /* 37 */
+ ProcRRConfigureProviderProperty, /* 38 */
+ ProcRRChangeProviderProperty, /* 39 */
+ ProcRRDeleteProviderProperty, /* 40 */
+ ProcRRGetProviderProperty, /* 41 */
+ ProcRRGetMonitors, /* 42 */
+ ProcRRSetMonitor, /* 43 */
+ ProcRRDeleteMonitor, /* 44 */
};
diff --git a/nx-X11/programs/Xserver/randr/rrinfo.c b/nx-X11/programs/Xserver/randr/rrinfo.c
index 070f5ca0c..df9b79986 100644
--- a/nx-X11/programs/Xserver/randr/rrinfo.c
+++ b/nx-X11/programs/Xserver/randr/rrinfo.c
@@ -36,7 +36,7 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
RRModePtr *modes;
memset(&modeInfo, '\0', sizeof(modeInfo));
- sprintf(name, "%dx%d", size->width, size->height);
+ snprintf(name, sizeof(name), "%dx%d", size->width, size->height);
modeInfo.width = size->width;
modeInfo.height = size->height;
@@ -55,8 +55,13 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
}
if (output->numModes)
+#ifndef NXAGENT_SERVER
+ modes = reallocarray(output->modes,
+ output->numModes + 1, sizeof(RRModePtr));
+#else /* !defined(NXAGENT_SERVER) */
modes = xrealloc(output->modes,
(output->numModes + 1) * sizeof(RRModePtr));
+#endif /* !defined(NXAGENT_SERVER) */
else
modes = xalloc(sizeof(RRModePtr));
if (!modes) {
@@ -97,9 +102,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
return;
RROutputSetCrtcs(output, &crtc, 1);
RROutputSetConnection(output, RR_Connected);
-#ifdef RENDER
RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen));
-#endif
}
output = pScrPriv->outputs[0];
@@ -145,7 +148,8 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
/* find size bounds */
for (i = 0; i < output->numModes + output->numUserModes; i++) {
mode = (i < output->numModes ?
- output->modes[i] : output->userModes[i - output->numModes]);
+ output->modes[i] :
+ output->userModes[i - output->numModes]);
width = mode->mode.width;
height = mode->mode.height;
@@ -163,7 +167,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
/* notice current mode */
if (newMode)
- RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, 1, &output);
+ RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, NULL, 1, &output);
}
#endif
@@ -171,12 +175,20 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
* Poll the driver for changed information
*/
Bool
-RRGetInfo(ScreenPtr pScreen)
+RRGetInfo(ScreenPtr pScreen, Bool force_query)
{
rrScrPriv(pScreen);
Rotation rotations;
int i;
+ /* Return immediately if we don't need to re-query and we already have the
+ * information.
+ */
+ if (!force_query) {
+ if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0)
+ return TRUE;
+ }
+
for (i = 0; i < pScrPriv->numOutputs; i++)
pScrPriv->outputs[i]->changed = FALSE;
for (i = 0; i < pScrPriv->numCrtcs; i++)
@@ -218,7 +230,7 @@ RRScreenSetSizeRange(ScreenPtr pScreen,
pScrPriv->minHeight = minHeight;
pScrPriv->maxWidth = maxWidth;
pScrPriv->maxHeight = maxHeight;
- pScrPriv->changed = TRUE;
+ RRSetChanged(pScreen);
pScrPriv->configChanged = TRUE;
}
@@ -259,8 +271,13 @@ RRRegisterSize(ScreenPtr pScreen,
for (i = 0; i < pScrPriv->nSizes; i++)
if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i]))
return &pScrPriv->pSizes[i];
+#ifndef NXAGENT_SERVER
+ pNew = reallocarray(pScrPriv->pSizes,
+ pScrPriv->nSizes + 1, sizeof(RRScreenSize));
+#else /* !defined(NXAGENT_SERVER) */
pNew = xrealloc(pScrPriv->pSizes,
(pScrPriv->nSizes + 1) * sizeof(RRScreenSize));
+#endif /* !defined(NXAGENT_SERVER) */
if (!pNew)
return 0;
pNew[pScrPriv->nSizes++] = tmp;
@@ -282,7 +299,11 @@ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate)
if (pSize->pRates[i].rate == rate)
return TRUE;
+#ifndef NXAGENT_SERVER
+ pNew = reallocarray(pSize->pRates, pSize->nRates + 1, sizeof(RRScreenRate));
+#else /* !defined(NXAGENT_SERVER) */
pNew = xrealloc(pSize->pRates, (pSize->nRates + 1) * sizeof(RRScreenRate));
+#endif /* !defined(NXAGENT_SERVER) */
if (!pNew)
return FALSE;
pRate = &pNew[pSize->nRates++];
diff --git a/nx-X11/programs/Xserver/randr/rrmode.c b/nx-X11/programs/Xserver/randr/rrmode.c
index 4fe116400..918e0f221 100644
--- a/nx-X11/programs/Xserver/randr/rrmode.c
+++ b/nx-X11/programs/Xserver/randr/rrmode.c
@@ -38,7 +38,6 @@
/**************************************************************************/
#include "randrstr.h"
-#include "registry.h"
RESTYPE RRModeType;
@@ -97,7 +96,12 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
mode->userScreen = userScreen;
if (num_modes)
+#ifndef NXAGENT_SERVER
+ newModes = reallocarray(modes, num_modes + 1, sizeof(RRModePtr));
+#else /* !defined(NXAGENT_SERVER) */
newModes = xrealloc(modes, (num_modes + 1) * sizeof(RRModePtr));
+#endif /* !defined(NXAGENT_SERVER) */
+
else
newModes = xalloc(sizeof(RRModePtr));
@@ -113,6 +117,7 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
}
modes = newModes;
modes[num_modes++] = mode;
+
/*
* give the caller a reference to this mode
*/
@@ -203,7 +208,11 @@ RRModesForScreen(ScreenPtr pScreen, int *num_ret)
RRModePtr *screen_modes;
int num_screen_modes = 0;
+#ifndef NXAGENT_SERVER
+ screen_modes = xallocarray((num_modes ? num_modes : 1), sizeof(RRModePtr));
+#else /* !defined(NXAGENT_SERVER) */
screen_modes = xalloc((num_modes ? num_modes : 1) * sizeof(RRModePtr));
+#endif /* !defined(NXAGENT_SERVER) */
if (!screen_modes)
return NULL;
@@ -268,13 +277,8 @@ RRModeDestroy(RRModePtr mode)
{
int m;
- if (--mode->refcnt > 0) {
-#ifdef DEBUG
- fprintf(stderr, "RRModeDestroy: mode [%s] ([%p]) refcnt [%d -> %d]\n",
- mode->name, mode, mode->refcnt + 1, mode->refcnt);
-#endif
+ if (--mode->refcnt > 0)
return;
- }
for (m = 0; m < num_modes; m++) {
if (modes[m] == mode) {
memmove(modes + m, modes + m + 1,
@@ -288,37 +292,46 @@ RRModeDestroy(RRModePtr mode)
}
}
-#ifdef DEBUG
- fprintf(stderr, "RRModeDestroy: destroyed mode [%s] ([%p])\n", mode->name,
- mode);
-#endif
xfree(mode);
}
static int
RRModeDestroyResource(void *value, XID pid)
{
-#ifdef DEBUG
- fprintf(stderr, "RRModeDestroyResource: mode [%s] ([%p]) refcnt [%d]\n",
- ((RRModePtr) value)->name, (RRModePtr) value,
- ((RRModePtr) value)->refcnt);
-#endif
RRModeDestroy((RRModePtr) value);
return 1;
}
+/*
+ * Initialize mode type
+ */
Bool
RRModeInit(void)
{
assert(num_modes == 0);
assert(modes == NULL);
- RRModeType = CreateNewResourceType(RRModeDestroyResource);
+ RRModeType = CreateNewResourceType(RRModeDestroyResource
+#ifndef NXAGENT_SERVER
+ , "MODE"
+#endif
+ );
if (!RRModeType)
return FALSE;
- RegisterResourceName(RRModeType, "MODE");
+
return TRUE;
}
+/*
+ * Initialize mode type error value
+ */
+void
+RRModeInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RRModeType, RRErrorBase + BadRRMode);
+#endif
+}
+
int
ProcRRCreateMode(ClientPtr client)
{
@@ -331,10 +344,11 @@ ProcRRCreateMode(ClientPtr client)
char *name;
int error, rc;
RRModePtr mode;
+ int n;
REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
#ifndef NXAGENT_SERVER
- rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
@@ -346,24 +360,23 @@ ProcRRCreateMode(ClientPtr client)
modeInfo = &stuff->modeInfo;
name = (char *) (stuff + 1);
- units_after = (stuff->length - (sizeof(xRRCreateModeReq) >> 2));
+ units_after = (stuff->length - bytes_to_int32(sizeof(xRRCreateModeReq)));
/* check to make sure requested name fits within the data provided */
- if ((int) (modeInfo->nameLength + 3) >> 2 > units_after)
+ if (bytes_to_int32(modeInfo->nameLength) > units_after)
return BadLength;
mode = RRModeCreateUser(pScreen, modeInfo, name, &error);
if (!mode)
return error;
- rep.type = X_Reply;
- rep.pad0 = 0;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.mode = mode->mode.id;
+ rep = (xRRCreateModeReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .mode = mode->mode.id
+ };
if (client->swapped) {
- int n;
-
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.mode, n);
@@ -371,7 +384,7 @@ ProcRRCreateMode(ClientPtr client)
WriteToClient(client, sizeof(xRRCreateModeReply), (char *) &rep);
/* Drop out reference to this mode */
RRModeDestroy(mode);
- return client->noClientException;
+ return Success;
}
int
@@ -381,11 +394,8 @@ ProcRRDestroyMode(ClientPtr client)
RRModePtr mode;
REQUEST_SIZE_MATCH(xRRDestroyModeReq);
- mode = LookupIDByType(stuff->mode, RRModeType);
- if (!mode) {
- client->errorValue = stuff->mode;
- return RRErrorBase + BadRRMode;
- }
+ VERIFY_RR_MODE(stuff->mode, mode, DixDestroyAccess);
+
if (!mode->userScreen)
return BadMatch;
if (mode->refcnt > 1)
@@ -402,18 +412,8 @@ ProcRRAddOutputMode(ClientPtr client)
RROutputPtr output;
REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
- output = LookupOutput(client, stuff->output, DixReadAccess);
-
- if (!output) {
- client->errorValue = stuff->output;
- return RRErrorBase + BadRROutput;
- }
-
- mode = LookupIDByType(stuff->mode, RRModeType);
- if (!mode) {
- client->errorValue = stuff->mode;
- return RRErrorBase + BadRRMode;
- }
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+ VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess);
return RROutputAddUserMode(output, mode);
}
@@ -426,18 +426,8 @@ ProcRRDeleteOutputMode(ClientPtr client)
RROutputPtr output;
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
- output = LookupOutput(client, stuff->output, DixReadAccess);
-
- if (!output) {
- client->errorValue = stuff->output;
- return RRErrorBase + BadRROutput;
- }
-
- mode = LookupIDByType(stuff->mode, RRModeType);
- if (!mode) {
- client->errorValue = stuff->mode;
- return RRErrorBase + BadRRMode;
- }
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+ VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess);
return RROutputDeleteUserMode(output, mode);
}
diff --git a/nx-X11/programs/Xserver/randr/rrmonitor.c b/nx-X11/programs/Xserver/randr/rrmonitor.c
new file mode 100644
index 000000000..fc9b9295b
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrmonitor.c
@@ -0,0 +1,792 @@
+/*
+ * Copyright © 2014 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"
+#include "swaprep.h"
+#ifndef NXAGENT_SERVER
+#include "list.h"
+#endif
+
+static Atom
+RRMonitorCrtcName(RRCrtcPtr crtc)
+{
+ char name[20];
+
+ if (crtc->numOutputs) {
+ RROutputPtr output = crtc->outputs[0];
+ return MakeAtom(output->name, output->nameLength, TRUE);
+ }
+ sprintf(name, "Monitor-%08lx", (unsigned long int) crtc->id);
+ return MakeAtom(name, strlen(name), TRUE);
+}
+
+static Bool
+RRMonitorCrtcPrimary(RRCrtcPtr crtc)
+{
+ ScreenPtr screen = crtc->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int o;
+
+ for (o = 0; o < crtc->numOutputs; o++)
+ if (crtc->outputs[o] == pScrPriv->primaryOutput)
+ return TRUE;
+ return FALSE;
+}
+
+#define DEFAULT_PIXELS_PER_MM (96.0 / 25.4)
+
+static void
+RRMonitorGetCrtcGeometry(RRCrtcPtr crtc, RRMonitorGeometryPtr geometry)
+{
+ ScreenPtr screen = crtc->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ BoxRec panned_area;
+
+ /* Check to see if crtc is panned and return the full area when applicable. */
+ if (pScrPriv && pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(screen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) &&
+ (panned_area.y2 > panned_area.y1)) {
+ geometry->box = panned_area;
+ }
+ else {
+ int width, height;
+
+ RRCrtcGetScanoutSize(crtc, &width, &height);
+ geometry->box.x1 = crtc->x;
+ geometry->box.y1 = crtc->y;
+ geometry->box.x2 = geometry->box.x1 + width;
+ geometry->box.y2 = geometry->box.y1 + height;
+ }
+ if (crtc->numOutputs && crtc->outputs[0]->mmWidth && crtc->outputs[0]->mmHeight) {
+ RROutputPtr output = crtc->outputs[0];
+ geometry->mmWidth = output->mmWidth;
+ geometry->mmHeight = output->mmHeight;
+ } else {
+ geometry->mmWidth = floor((geometry->box.x2 - geometry->box.x1) / DEFAULT_PIXELS_PER_MM + 0.5);
+ geometry->mmHeight = floor((geometry->box.y2 - geometry->box.y1) / DEFAULT_PIXELS_PER_MM + 0.5);
+ }
+}
+
+static Bool
+RRMonitorSetFromServer(RRCrtcPtr crtc, RRMonitorPtr monitor)
+{
+ int o;
+
+ monitor->name = RRMonitorCrtcName(crtc);
+ monitor->pScreen = crtc->pScreen;
+ monitor->numOutputs = crtc->numOutputs;
+ monitor->outputs = xcalloc(crtc->numOutputs, sizeof(RRCrtc));
+ if (!monitor->outputs)
+ return FALSE;
+ for (o = 0; o < crtc->numOutputs; o++)
+ monitor->outputs[o] = crtc->outputs[o]->id;
+ monitor->primary = RRMonitorCrtcPrimary(crtc);
+ monitor->automatic = TRUE;
+ RRMonitorGetCrtcGeometry(crtc, &monitor->geometry);
+ return TRUE;
+}
+
+static Bool
+RRMonitorAutomaticGeometry(RRMonitorPtr monitor)
+{
+ return (monitor->geometry.box.x1 == 0 &&
+ monitor->geometry.box.y1 == 0 &&
+ monitor->geometry.box.x2 == 0 &&
+ monitor->geometry.box.y2 == 0);
+}
+
+static void
+RRMonitorGetGeometry(RRMonitorPtr monitor, RRMonitorGeometryPtr geometry)
+{
+ if (RRMonitorAutomaticGeometry(monitor) && monitor->numOutputs > 0) {
+ ScreenPtr screen = monitor->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ RRMonitorGeometryRec first = { .box = {0, 0, 0, 0}, .mmWidth = 0, .mmHeight = 0 };
+ RRMonitorGeometryRec this;
+ int c, o, co;
+ int active_crtcs = 0;
+
+ *geometry = first;
+ for (o = 0; o < monitor->numOutputs; o++) {
+ RRCrtcPtr crtc = NULL;
+ Bool in_use = FALSE;
+
+ for (c = 0; !in_use && c < pScrPriv->numCrtcs; c++) {
+ crtc = pScrPriv->crtcs[c];
+ if (!crtc->mode)
+ continue;
+ for (co = 0; !in_use && co < crtc->numOutputs; co++)
+ if (monitor->outputs[o] == crtc->outputs[co]->id)
+ in_use = TRUE;
+ }
+
+ if (!in_use)
+ continue;
+
+ RRMonitorGetCrtcGeometry(crtc, &this);
+
+ if (active_crtcs == 0) {
+ first = this;
+ *geometry = this;
+ } else {
+ geometry->box.x1 = min(this.box.x1, geometry->box.x1);
+ geometry->box.x2 = max(this.box.x2, geometry->box.x2);
+ geometry->box.y1 = min(this.box.y1, geometry->box.y1);
+ geometry->box.y2 = max(this.box.y2, geometry->box.y2);
+ }
+ active_crtcs++;
+ }
+
+ /* Adjust physical sizes to account for total area */
+ if (active_crtcs > 1 && first.box.x2 != first.box.x1 && first.box.y2 != first.box.y1) {
+ geometry->mmWidth = (this.box.x2 - this.box.x1) / (first.box.x2 - first.box.x1) * first.mmWidth;
+ geometry->mmHeight = (this.box.y2 - this.box.y1) / (first.box.y2 - first.box.y1) * first.mmHeight;
+ }
+ } else {
+ *geometry = monitor->geometry;
+ }
+}
+
+static Bool
+RRMonitorSetFromClient(RRMonitorPtr client_monitor, RRMonitorPtr monitor)
+{
+ monitor->name = client_monitor->name;
+ monitor->pScreen = client_monitor->pScreen;
+ monitor->numOutputs = client_monitor->numOutputs;
+ monitor->outputs = xcalloc(client_monitor->numOutputs, sizeof(RROutput));
+ if (!monitor->outputs && client_monitor->numOutputs)
+ return FALSE;
+ memcpy(monitor->outputs, client_monitor->outputs, client_monitor->numOutputs * sizeof(RROutput));
+ monitor->primary = client_monitor->primary;
+ monitor->automatic = client_monitor->automatic;
+ RRMonitorGetGeometry(client_monitor, &monitor->geometry);
+ return TRUE;
+}
+
+typedef struct _rrMonitorList {
+ int num_client;
+ int num_server;
+ RRCrtcPtr *server_crtc;
+ int num_crtcs;
+ int client_primary;
+ int server_primary;
+} RRMonitorListRec, *RRMonitorListPtr;
+
+static Bool
+RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m, o, c, sc;
+ int numCrtcs;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+
+ if (!RRGetInfo(screen, FALSE))
+ return FALSE;
+
+ /* Count the number of crtcs in this and any slave screens */
+ numCrtcs = pScrPriv->numCrtcs;
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+ numCrtcs += pSlavePriv->numCrtcs;
+ }
+#endif
+ mon_list->num_crtcs = numCrtcs;
+
+ mon_list->server_crtc = xcalloc(numCrtcs * 2, sizeof(RRCrtcPtr));
+ if (!mon_list->server_crtc)
+ return FALSE;
+
+ /* Collect pointers to all of the active crtcs */
+ c = 0;
+ for (sc = 0; sc < pScrPriv->numCrtcs; sc++, c++) {
+ if (pScrPriv->crtcs[sc]->mode != NULL)
+ mon_list->server_crtc[c] = pScrPriv->crtcs[sc];
+ }
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+ for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) {
+ if (pSlavePriv->crtcs[sc]->mode != NULL)
+ mon_list->server_crtc[c] = pSlavePriv->crtcs[sc];
+ }
+ }
+#endif
+
+ /* Walk the list of client-defined monitors, clearing the covered
+ * CRTCs from the full list and finding whether one of the
+ * monitors is primary
+ */
+ mon_list->num_client = pScrPriv->numMonitors;
+ mon_list->client_primary = -1;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr monitor = pScrPriv->monitors[m];
+ if (get_active) {
+ RRMonitorGeometryRec geom;
+
+ RRMonitorGetGeometry(monitor, &geom);
+ if (geom.box.x2 - geom.box.x1 == 0 ||
+ geom.box.y2 - geom.box.y1 == 0) {
+ mon_list->num_client--;
+ continue;
+ }
+ }
+ if (monitor->primary && mon_list->client_primary == -1)
+ mon_list->client_primary = m;
+ for (o = 0; o < monitor->numOutputs; o++) {
+ for (c = 0; c < numCrtcs; c++) {
+ RRCrtcPtr crtc = mon_list->server_crtc[c];
+ if (crtc) {
+ int co;
+ for (co = 0; co < crtc->numOutputs; co++)
+ if (crtc->outputs[co]->id == monitor->outputs[o]) {
+ mon_list->server_crtc[c] = NULL;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Now look at the active CRTCs, and count
+ * those not covered by a client monitor, as well
+ * as finding whether one of them is marked primary
+ */
+ mon_list->num_server = 0;
+ mon_list->server_primary = -1;
+
+ for (c = 0; c < mon_list->num_crtcs; c++) {
+ RRCrtcPtr crtc = mon_list->server_crtc[c];
+
+ if (!crtc)
+ continue;
+
+ mon_list->num_server++;
+
+ if (RRMonitorCrtcPrimary(crtc) && mon_list->server_primary == -1)
+ mon_list->server_primary = c;
+ }
+ return TRUE;
+}
+
+static void
+RRMonitorFiniList(RRMonitorListPtr list)
+{
+ xfree(list->server_crtc);
+}
+
+/* Construct a complete list of protocol-visible monitors, including
+ * the manually generated ones as well as those generated
+ * automatically from the remaining CRCTs
+ */
+
+Bool
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr * monitors_ret, int *nmon_ret)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ RRMonitorListRec list;
+ int m, c;
+ RRMonitorPtr mon, monitors;
+ Bool has_primary = FALSE;
+
+ if (!pScrPriv)
+ return FALSE;
+
+ if (!RRMonitorInitList(screen, &list, get_active))
+ return FALSE;
+
+ monitors = xcalloc(list.num_client + list.num_server, sizeof(RRMonitorRec));
+ if (!monitors) {
+ RRMonitorFiniList(&list);
+ return FALSE;
+ }
+
+ mon = monitors;
+
+ /* Fill in the primary monitor data first
+ */
+ if (list.client_primary >= 0) {
+ RRMonitorSetFromClient(pScrPriv->monitors[list.client_primary], mon);
+ mon++;
+ } else if (list.server_primary >= 0) {
+ RRMonitorSetFromServer(list.server_crtc[list.server_primary], mon);
+ mon++;
+ }
+
+ /* Fill in the client-defined monitors next
+ */
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ if (m == list.client_primary)
+ continue;
+ if (get_active) {
+ RRMonitorGeometryRec geom;
+
+ RRMonitorGetGeometry(pScrPriv->monitors[m], &geom);
+ if (geom.box.x2 - geom.box.x1 == 0 ||
+ geom.box.y2 - geom.box.y1 == 0) {
+ continue;
+ }
+ }
+ RRMonitorSetFromClient(pScrPriv->monitors[m], mon);
+ if (has_primary)
+ mon->primary = FALSE;
+ else if (mon->primary)
+ has_primary = TRUE;
+ mon++;
+ }
+
+ /* And finish with the list of crtc-inspired monitors
+ */
+ for (c = 0; c < list.num_crtcs; c++) {
+ RRCrtcPtr crtc = list.server_crtc[c];
+ if (c == list.server_primary && list.client_primary < 0)
+ continue;
+
+ if (!list.server_crtc[c])
+ continue;
+
+ RRMonitorSetFromServer(crtc, mon);
+ if (has_primary)
+ mon->primary = FALSE;
+ else if (mon->primary)
+ has_primary = TRUE;
+ mon++;
+ }
+
+ RRMonitorFiniList(&list);
+ *nmon_ret = list.num_client + list.num_server;
+ *monitors_ret = monitors;
+ return TRUE;
+}
+
+int
+RRMonitorCountList(ScreenPtr screen)
+{
+ RRMonitorListRec list;
+ int nmon;
+
+ if (!RRMonitorInitList(screen, &list, FALSE))
+ return -1;
+ nmon = list.num_client + list.num_server;
+ RRMonitorFiniList(&list);
+ return nmon;
+}
+
+void
+RRMonitorFree(RRMonitorPtr monitor)
+{
+ xfree(monitor);
+}
+
+RRMonitorPtr
+RRMonitorAlloc(int noutput)
+{
+ RRMonitorPtr monitor;
+
+ monitor = xcalloc(1, sizeof(RRMonitorRec) + noutput * sizeof(RROutput));
+ if (!monitor)
+ return NULL;
+ monitor->numOutputs = noutput;
+ monitor->outputs = (RROutput *) (monitor + 1);
+ return monitor;
+}
+
+static int
+RRMonitorDelete(ClientPtr client, ScreenPtr screen, Atom name)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+
+ if (!pScrPriv) {
+ client->errorValue = name;
+ return BadAtom;
+ }
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr monitor = pScrPriv->monitors[m];
+ if (monitor->name == name) {
+ memmove(pScrPriv->monitors + m, pScrPriv->monitors + m + 1,
+ (pScrPriv->numMonitors - (m + 1)) * sizeof(RRMonitorPtr));
+ --pScrPriv->numMonitors;
+ RRMonitorFree(monitor);
+ return Success;
+ }
+ }
+
+ client->errorValue = name;
+ return BadValue;
+}
+
+static Bool
+RRMonitorMatchesOutputName(ScreenPtr screen, Atom name)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int o;
+ const char *str = NameForAtom(name);
+ int len = strlen(str);
+
+ for (o = 0; o < pScrPriv->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->outputs[o];
+
+ if (output->nameLength == len && !memcmp(output->name, str, len))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+ RRMonitorPtr *monitors;
+
+ if (!pScrPriv)
+ return BadAlloc;
+
+ /* 'name' must not match the name of any Output on the screen, or
+ * a Value error results.
+ */
+
+ if (RRMonitorMatchesOutputName(screen, monitor->name)) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ if (RRMonitorMatchesOutputName(slave, monitor->name)) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+ }
+#endif
+
+ /* 'name' must not match the name of any Monitor on the screen, or
+ * a Value error results.
+ */
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ if (pScrPriv->monitors[m]->name == monitor->name) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+ }
+
+ /* Allocate space for the new pointer. This is done before
+ * removing matching monitors as it may fail, and the request
+ * needs to not have any side-effects on failure
+ */
+ if (pScrPriv->numMonitors)
+#ifndef NXAGENT_SERVER
+ monitors = reallocarray(pScrPriv->monitors,
+ pScrPriv->numMonitors + 1,
+ sizeof(RRMonitorPtr));
+#else /* !defined(NXAGENT_SERVER) */
+ monitors = xrealloc(pScrPriv->monitors,
+ (pScrPriv->numMonitors + 1) * sizeof(RRMonitorPtr));
+#endif /* !defined(NXAGENT_SERVER) */
+ else
+ monitors = xalloc(sizeof(RRMonitorPtr));
+
+ if (!monitors)
+ return BadAlloc;
+
+ pScrPriv->monitors = monitors;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr existing = pScrPriv->monitors[m];
+ int o, eo;
+
+ /* If 'name' matches an existing Monitor on the screen, the
+ * existing one will be deleted as if RRDeleteMonitor were called.
+ */
+ if (existing->name == monitor->name) {
+ (void) RRMonitorDelete(client, screen, existing->name);
+ continue;
+ }
+
+ /* For each output in 'info.outputs', each one is removed from all
+ * pre-existing Monitors. If removing the output causes the list
+ * of outputs for that Monitor to become empty, then that
+ * Monitor will be deleted as if RRDeleteMonitor were called.
+ */
+
+ for (eo = 0; eo < existing->numOutputs; eo++) {
+ for (o = 0; o < monitor->numOutputs; o++) {
+ if (monitor->outputs[o] == existing->outputs[eo]) {
+ memmove(existing->outputs + eo, existing->outputs + eo + 1,
+ (existing->numOutputs - (eo + 1)) * sizeof(RROutput));
+ --existing->numOutputs;
+ --eo;
+ break;
+ }
+ }
+ if (existing->numOutputs == 0) {
+ (void) RRMonitorDelete(client, screen, existing->name);
+ break;
+ }
+ }
+ if (monitor->primary)
+ existing->primary = FALSE;
+ }
+
+ /* Add the new one to the list
+ */
+ pScrPriv->monitors[pScrPriv->numMonitors++] = monitor;
+
+ return Success;
+}
+
+void
+RRMonitorFreeList(RRMonitorPtr monitors, int nmon)
+{
+ int m;
+
+ for (m = 0; m < nmon; m++)
+ xfree(monitors[m].outputs);
+ xfree(monitors);
+}
+
+void
+RRMonitorInit(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+
+ if (!pScrPriv)
+ return;
+
+ pScrPriv->numMonitors = 0;
+ pScrPriv->monitors = NULL;
+}
+
+void
+RRMonitorClose(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+
+ if (!pScrPriv)
+ return;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++)
+ RRMonitorFree(pScrPriv->monitors[m]);
+ xfree(pScrPriv->monitors);
+ pScrPriv->monitors = NULL;
+ pScrPriv->numMonitors = 0;
+}
+
+static CARD32
+RRMonitorTimestamp(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+
+ /* XXX should take client monitor changes into account */
+ return pScrPriv->lastConfigTime.milliseconds;
+}
+
+int
+ProcRRGetMonitors(ClientPtr client)
+{
+ REQUEST(xRRGetMonitorsReq);
+ xRRGetMonitorsReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ };
+ WindowPtr window;
+ ScreenPtr screen;
+ int r;
+ RRMonitorPtr monitors;
+ int nmonitors;
+ int noutputs;
+ int m, n;
+ Bool get_active;
+
+ REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+#ifndef NXAGENT_SERVER
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+#else
+ window = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
+ r = window ? Success : BadWindow;
+#endif
+
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ get_active = stuff->get_active;
+ if (!RRMonitorMakeList(screen, get_active, &monitors, &nmonitors))
+ return BadAlloc;
+
+ rep.timestamp = RRMonitorTimestamp(screen);
+
+ noutputs = 0;
+ for (m = 0; m < nmonitors; m++) {
+ rep.length += SIZEOF(xRRMonitorInfo) >> 2;
+ rep.length += monitors[m].numOutputs;
+ noutputs += monitors[m].numOutputs;
+ }
+
+ rep.nmonitors = nmonitors;
+ rep.noutputs = noutputs;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swapl(&rep.nmonitors, n);
+ swapl(&rep.noutputs, n);
+ }
+ WriteToClient(client, sizeof(xRRGetMonitorsReply), (char *) &rep);
+
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+
+ for (m = 0; m < nmonitors; m++) {
+ RRMonitorPtr monitor = &monitors[m];
+ xRRMonitorInfo info = {
+ .name = monitor->name,
+ .primary = monitor->primary,
+ .automatic = monitor->automatic,
+ .noutput = monitor->numOutputs,
+ .x = monitor->geometry.box.x1,
+ .y = monitor->geometry.box.y1,
+ .width = monitor->geometry.box.x2 - monitor->geometry.box.x1,
+ .height = monitor->geometry.box.y2 - monitor->geometry.box.y1,
+ .widthInMillimeters = monitor->geometry.mmWidth,
+ .heightInMillimeters = monitor->geometry.mmHeight,
+ };
+ if (client->swapped) {
+ swapl(&info.name, n);
+ swaps(&info.noutput, n);
+ swaps(&info.x, n);
+ swaps(&info.y, n);
+ swaps(&info.width, n);
+ swaps(&info.height, n);
+ swapl(&info.widthInMillimeters, n);
+ swapl(&info.heightInMillimeters, n);
+ }
+
+ WriteToClient(client, sizeof(xRRMonitorInfo), (char *) &info);
+ WriteSwappedDataToClient(client, monitor->numOutputs * sizeof(RROutput),
+ monitor->outputs);
+ }
+
+ RRMonitorFreeList(monitors, nmonitors);
+
+ return Success;
+}
+
+int
+ProcRRSetMonitor(ClientPtr client)
+{
+ REQUEST(xRRSetMonitorReq);
+ WindowPtr window;
+ ScreenPtr screen;
+ RRMonitorPtr monitor;
+ int r;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetMonitorReq);
+
+ if (stuff->monitor.noutput != stuff->length - (SIZEOF(xRRSetMonitorReq) >> 2))
+ return BadLength;
+
+#ifndef NXAGENT_SERVER
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+#else
+ window = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
+ r = window ? Success : BadWindow;
+#endif
+
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ if (!ValidAtom(stuff->monitor.name))
+ return BadAtom;
+
+ /* Allocate the new monitor */
+ monitor = RRMonitorAlloc(stuff->monitor.noutput);
+ if (!monitor)
+ return BadAlloc;
+
+ /* Fill in the bits from the request */
+ monitor->pScreen = screen;
+ monitor->name = stuff->monitor.name;
+ monitor->primary = stuff->monitor.primary;
+ monitor->automatic = FALSE;
+ memcpy(monitor->outputs, stuff + 1, stuff->monitor.noutput * sizeof(RROutput));
+ monitor->geometry.box.x1 = stuff->monitor.x;
+ monitor->geometry.box.y1 = stuff->monitor.y;
+ monitor->geometry.box.x2 = stuff->monitor.x + stuff->monitor.width;
+ monitor->geometry.box.y2 = stuff->monitor.y + stuff->monitor.height;
+ monitor->geometry.mmWidth = stuff->monitor.widthInMillimeters;
+ monitor->geometry.mmHeight = stuff->monitor.heightInMillimeters;
+
+ r = RRMonitorAdd(client, screen, monitor);
+ if (r == Success)
+ RRSendConfigNotify(screen);
+ else
+ RRMonitorFree(monitor);
+ return r;
+}
+
+int
+ProcRRDeleteMonitor(ClientPtr client)
+{
+ REQUEST(xRRDeleteMonitorReq);
+ WindowPtr window;
+ ScreenPtr screen;
+ int r;
+
+ REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+#ifndef NXAGENT_SERVER
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+#else
+ window = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
+ r = window ? Success : BadWindow;
+#endif
+
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ if (!ValidAtom(stuff->name)) {
+ client->errorValue = stuff->name;
+ return BadAtom;
+ }
+
+ r = RRMonitorDelete(client, screen, stuff->name);
+ if (r == Success)
+ RRSendConfigNotify(screen);
+ return r;
+}
diff --git a/nx-X11/programs/Xserver/randr/rroutput.c b/nx-X11/programs/Xserver/randr/rroutput.c
index 523ee55d8..2628fabb0 100644
--- a/nx-X11/programs/Xserver/randr/rroutput.c
+++ b/nx-X11/programs/Xserver/randr/rroutput.c
@@ -1,5 +1,6 @@
/*
* 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
@@ -21,7 +22,6 @@
*/
#include "randrstr.h"
-#include "registry.h"
RESTYPE RROutputType;
@@ -31,15 +31,30 @@ RESTYPE RROutputType;
void
RROutputChanged(RROutputPtr output, Bool configChanged)
{
+ /* set changed bits on the master screen only */
ScreenPtr pScreen = output->pScreen;
+ rrScrPrivPtr mastersp;
output->changed = TRUE;
- if (pScreen) {
- rrScrPriv(pScreen);
- pScrPriv->changed = TRUE;
- if (configChanged)
- pScrPriv->configChanged = TRUE;
+ if (!pScreen)
+ return;
+
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ ScreenPtr master = pScreen->current_master;
+ if (!master)
+ return;
+ mastersp = rrGetScrPriv(master);
}
+ else
+#endif
+ {
+ mastersp = rrGetScrPriv(pScreen);
+ }
+
+ RRSetChanged(pScreen);
+ if (configChanged)
+ mastersp->configChanged = TRUE;
}
/*
@@ -60,8 +75,13 @@ RROutputCreate(ScreenPtr pScreen,
pScrPriv = rrGetScrPriv(pScreen);
if (pScrPriv->numOutputs)
+#ifndef NXAGENT_SERVER
+ outputs = reallocarray(pScrPriv->outputs,
+ pScrPriv->numOutputs + 1, sizeof(RROutputPtr));
+#else /* !defined(NXAGENT_SERVER) */
outputs = xrealloc(pScrPriv->outputs,
(pScrPriv->numOutputs + 1) * sizeof(RROutputPtr));
+#endif /* !defined(NXAGENT_SERVER) */
else
outputs = xalloc(sizeof(RROutputPtr));
if (!outputs)
@@ -101,6 +121,9 @@ RROutputCreate(ScreenPtr pScreen,
return NULL;
pScrPriv->outputs[pScrPriv->numOutputs++] = output;
+
+ RRResourcesChanged(pScreen);
+
return output;
}
@@ -121,14 +144,17 @@ RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones)
return TRUE;
}
if (numClones) {
+#ifndef NXAGENT_SERVER
+ newClones = xallocarray(numClones, sizeof(RROutputPtr));
+#else /* !defined(NXAGENT_SERVER) */
newClones = xalloc(numClones * sizeof(RROutputPtr));
+#endif /* !defined(NXAGENT_SERVER) */
if (!newClones)
return FALSE;
}
else
newClones = NULL;
- if (output->clones)
- xfree(output->clones);
+ xfree(output->clones);
memcpy(newClones, clones, numClones * sizeof(RROutputPtr));
output->clones = newClones;
output->numClones = numClones;
@@ -155,7 +181,11 @@ RROutputSetModes(RROutputPtr output,
}
if (numModes) {
+#ifndef NXAGENT_SERVER
+ newModes = xallocarray(numModes, sizeof(RRModePtr));
+#else /* !defined(NXAGENT_SERVER) */
newModes = xalloc(numModes * sizeof(RRModePtr));
+#endif /* !defined(NXAGENT_SERVER) */
if (!newModes)
return FALSE;
}
@@ -198,8 +228,13 @@ RROutputAddUserMode(RROutputPtr output, RRModePtr mode)
return BadMatch;
if (output->userModes)
+#ifndef NXAGENT_SERVER
+ newModes = reallocarray(output->userModes,
+ output->numUserModes + 1, sizeof(RRModePtr));
+#else /* !defined(NXAGENT_SERVER) */
newModes = xrealloc(output->userModes,
(output->numUserModes + 1) * sizeof(RRModePtr));
+#endif /* !defined(NXAGENT_SERVER) */
else
newModes = xalloc(sizeof(RRModePtr));
if (!newModes)
@@ -254,14 +289,17 @@ RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs)
return TRUE;
}
if (numCrtcs) {
+#ifndef NXAGENT_SERVER
+ newCrtcs = xallocarray(numCrtcs, sizeof(RRCrtcPtr));
+#else /* !defined(NXAGENT_SERVER) */
newCrtcs = xalloc(numCrtcs * sizeof(RRCrtcPtr));
+#endif /* !defined(NXAGENT_SERVER) */
if (!newCrtcs)
return FALSE;
}
else
newCrtcs = NULL;
- if (output->crtcs)
- xfree(output->crtcs);
+ xfree(output->crtcs);
memcpy(newCrtcs, crtcs, numCrtcs * sizeof(RRCrtcPtr));
output->crtcs = newCrtcs;
output->numCrtcs = numCrtcs;
@@ -307,29 +345,25 @@ 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;
+ RRModePtr mode = crtc ? crtc->mode : NULL;
+
+ xRROutputChangeNotifyEvent oe = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_OutputChange,
+#ifdef NXAGENT_SERVER
+ .sequenceNumber = client->sequence,
+#endif
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .window = pWin->drawable.id,
+ .output = output->id,
+ .crtc = crtc ? crtc->id : None,
+ .mode = mode ? mode->mode.id : None,
+ .rotation = crtc ? crtc->rotation : RR_Rotate_0,
+ .connection = output->connection,
+ .subpixelOrder = output->subpixelOrder
+ };
WriteEventsToClient(client, 1, (xEvent *) &oe);
}
@@ -353,6 +387,9 @@ RROutputDestroyResource(void *value, XID pid)
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,
@@ -361,6 +398,8 @@ RROutputDestroyResource(void *value, XID pid)
break;
}
}
+
+ RRResourcesChanged(pScreen);
}
if (output->modes) {
for (m = 0; m < output->numModes; m++)
@@ -370,13 +409,10 @@ RROutputDestroyResource(void *value, XID pid)
for (m = 0; m < output->numUserModes; m++)
RRModeDestroy(output->userModes[m]);
- if (output->userModes)
- xfree(output->userModes);
+ xfree(output->userModes);
- if (output->crtcs)
- xfree(output->crtcs);
- if (output->clones)
- xfree(output->clones);
+ xfree(output->crtcs);
+ xfree(output->clones);
RRDeleteAllOutputProperties(output);
xfree(output);
return 1;
@@ -388,13 +424,28 @@ RROutputDestroyResource(void *value, XID pid)
Bool
RROutputInit(void)
{
- RROutputType = CreateNewResourceType(RROutputDestroyResource);
+ RROutputType = CreateNewResourceType(RROutputDestroyResource
+#ifndef NXAGENT_SERVER
+ , "OUTPUT"
+#endif
+ );
if (!RROutputType)
return FALSE;
- RegisterResourceName(RROutputType, "OUTPUT");
+
return TRUE;
}
+/*
+ * Initialize output type error value
+ */
+void
+RROutputInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RROutputType, RRErrorBase + BadRROutput);
+#endif
+}
+
#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
int
@@ -411,41 +462,38 @@ ProcRRGetOutputInfo(ClientPtr client)
RRMode *modes;
RROutput *clones;
char *name;
- int i, n;
+ int i;
+ int n;
REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
- output = LookupOutput(client, stuff->output, DixReadAccess);
-
- if (!output) {
- client->errorValue = stuff->output;
- return RRErrorBase + BadRROutput;
- }
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
pScreen = output->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
- rep.type = X_Reply;
- rep.status = RRSetConfigSuccess;
- rep.sequenceNumber = client->sequence;
- rep.length = OutputInfoExtra >> 2;
- 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;
-
+ rep = (xRRGetOutputInfoReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(OutputInfoExtra),
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .crtc = output->crtc ? output->crtc->id : None,
+ .mmWidth = output->mmWidth,
+ .mmHeight = output->mmHeight,
+ .connection = output->connection,
+ .subpixelOrder = output->subpixelOrder,
+ .nCrtcs = output->numCrtcs,
+ .nModes = output->numModes + output->numUserModes,
+ .nPreferred = output->numPreferred,
+ .nClones = output->numClones,
+ .nameLength = output->nameLength
+ };
extraLen = ((output->numCrtcs +
- output->numModes + output->numUserModes +
- output->numClones + ((rep.nameLength + 3) >> 2)) << 2);
+ output->numModes + output->numUserModes +
+ output->numClones + bytes_to_int32(rep.nameLength)) << 2);
if (extraLen) {
- rep.length += extraLen >> 2;
+ rep.length += bytes_to_int32(extraLen);
extra = xalloc(extraLen);
if (!extra)
return BadAlloc;
@@ -486,6 +534,7 @@ ProcRRGetOutputInfo(ClientPtr client)
swapl(&rep.mmHeight, n);
swaps(&rep.nCrtcs, n);
swaps(&rep.nModes, n);
+ swaps(&rep.nPreferred, n);
swaps(&rep.nClones, n);
swaps(&rep.nameLength, n);
}
@@ -495,5 +544,130 @@ ProcRRGetOutputInfo(ClientPtr client)
xfree(extra);
}
- return client->noClientException;
+ 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 ret;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+
+#ifndef NXAGENT_SERVER
+ ret = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
+ ret = pWin ? Success : BadWindow;
+#endif
+
+ if (ret != Success)
+ return ret;
+
+ if (stuff->output) {
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+#ifndef NXAGENT_SERVER
+ if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) {
+ client->errorValue = stuff->window;
+ return BadMatch;
+ }
+ if (output->pScreen->isGPU &&
+ output->pScreen->current_master != pWin->drawable.pScreen) {
+ client->errorValue = stuff->window;
+ return BadMatch;
+ }
+#endif
+ }
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ if (pScrPriv)
+ {
+ RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave,
+ &pWin->drawable.pScreen->output_slave_list,
+ output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+
+ RRSetPrimaryOutput(slave, pSlavePriv, output);
+ }
+#endif
+ }
+
+ return Success;
+}
+
+int
+ProcRRGetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPrimaryReq);
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+ xRRGetOutputPrimaryReply rep;
+ RROutputPtr primary = NULL;
+ int rc;
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ if (pScrPriv)
+ primary = pScrPriv->primaryOutput;
+
+ rep = (xRRGetOutputPrimaryReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .output = primary ? primary->id : None
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.output, n);
+ }
+
+ WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), (char *) &rep);
+
+ return Success;
}
diff --git a/nx-X11/programs/Xserver/randr/rrpointer.c b/nx-X11/programs/Xserver/randr/rrpointer.c
index 811310985..ace7d36a2 100644
--- a/nx-X11/programs/Xserver/randr/rrpointer.c
+++ b/nx-X11/programs/Xserver/randr/rrpointer.c
@@ -21,6 +21,7 @@
*/
#include "randrstr.h"
+#include "inputstr.h"
/*
* When the pointer moves, check to see if the specified position is outside
@@ -51,7 +52,11 @@ RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y)
* Find the CRTC nearest the specified position, ignoring 'skip'
*/
static void
-RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
+RRPointerToNearestCrtc(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
{
rrScrPriv(pScreen);
int c;
@@ -75,25 +80,31 @@ RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
if (x < crtc->x)
dx = crtc->x - x;
- else if (x > crtc->x + scan_width)
- dx = x - (crtc->x + scan_width);
+ else if (x > crtc->x + scan_width - 1)
+ dx = crtc->x + (scan_width - 1) - x;
else
dx = 0;
if (y < crtc->y)
- dy = crtc->y - x;
- else if (y > crtc->y + scan_height)
- dy = y - (crtc->y + scan_height);
+ dy = crtc->y - y;
+ else if (y > crtc->y + scan_height - 1)
+ dy = crtc->y + (scan_height - 1) - y;
else
dy = 0;
- dist = dx + dy;
+ dist = dx * dx + dy * dy;
if (!nearest || dist < best) {
nearest = crtc;
best_dx = dx;
best_dy = dy;
+ best = dist;
}
}
if (best_dx || best_dy)
- (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE);
+ (*pScreen->SetCursorPosition) (
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ pScreen, x + best_dx, y + best_dy,
+ TRUE);
pScrPriv->pointerCrtc = nearest;
}
@@ -120,22 +131,52 @@ RRPointerMoved(ScreenPtr pScreen, int x, int y)
}
/* None contain pointer, find nearest */
- RRPointerToNearestCrtc(pScreen, x, y, pointerCrtc);
+ ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n");
+ RRPointerToNearestCrtc(
+#ifndef NXAGENT_SERVER
+ inputInfo.pointer,
+#endif /* !defined(NXAGENT_SERVER) */
+ pScreen, x, y, pointerCrtc);
}
/*
- * When the screen is reconfigured, move the pointer to the nearest
+ * When the screen is reconfigured, move all pointers to the nearest
* CRTC
*/
void
RRPointerScreenConfigured(ScreenPtr pScreen)
{
- WindowPtr pRoot = GetCurrentRootWindow();
- ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+ WindowPtr pRoot;
+ ScreenPtr pCurrentScreen;
int x, y;
- if (pScreen != pCurrentScreen)
- return;
- GetSpritePosition(&x, &y);
- RRPointerToNearestCrtc(pScreen, x, y, NULL);
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev;
+
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
+ if (IsPointerDevice(pDev)) {
+#endif /* NXAGENT_SERVER */
+ pRoot = GetCurrentRootWindow(
+#ifndef NXAGENT_SERVER
+ pDev
+#endif /* NXAGENT_SERVER */
+ );
+ pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+
+ if (pScreen == pCurrentScreen) {
+ GetSpritePosition(
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* NXAGENT_SERVER */
+ &x, &y);
+ RRPointerToNearestCrtc(
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* NXAGENT_SERVER */
+ pScreen, x, y, NULL);
+#ifndef NXAGENT_SERVER
+ }
+ }
+#endif /* NXAGENT_SERVER */
+ }
}
diff --git a/nx-X11/programs/Xserver/randr/rrproperty.c b/nx-X11/programs/Xserver/randr/rrproperty.c
index 0bccb0c68..741d0310e 100644
--- a/nx-X11/programs/Xserver/randr/rrproperty.c
+++ b/nx-X11/programs/Xserver/randr/rrproperty.c
@@ -24,33 +24,76 @@
#include "propertyst.h"
#include "swaprep.h"
+static int
+DeliverPropertyEvent(WindowPtr pWin, void *value)
+{
+ xRROutputPropertyNotifyEvent *event = value;
+ RREventPtr *pHead, pRREvent;
+
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixReadAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (!(pRREvent->mask & RROutputPropertyNotifyMask))
+ continue;
+
+#ifdef NXAGENT_SERVER
+ event->sequenceNumber = pRREvent->client->sequence;
+#endif
+ event->window = pRREvent->window->drawable.id;
+ WriteEventsToClient(pRREvent->client, 1, (xEvent *) event);
+ }
+
+ return WT_WALKCHILDREN;
+}
+
static void
-RRDeliverEvent(ScreenPtr pScreen, xEvent *event, CARD32 mask)
+RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
{
+ if (!(dispatchException & (DE_RESET | DE_TERMINATE)))
+ WalkTree(pScreen, DeliverPropertyEvent, event);
+}
+static void
+RRDestroyOutputProperty(RRPropertyPtr prop)
+{
+ xfree(prop->valid_values);
+ xfree(prop->current.data);
+ xfree(prop->pending.data);
+ xfree(prop);
+}
+
+static void
+RRDeleteProperty(RROutputRec * output, RRPropertyRec * prop)
+{
+ xRROutputPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_OutputProperty,
+ .output = output->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+
+ RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event);
+
+ RRDestroyOutputProperty(prop);
}
void
RRDeleteAllOutputProperties(RROutputPtr output)
{
RRPropertyPtr prop, next;
- xRROutputPropertyNotifyEvent event;
for (prop = output->properties; prop; prop = next) {
next = prop->next;
- event.type = RREventBase + RRNotify;
- event.subCode = RRNotify_OutputProperty;
- event.output = output->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.timestamp = currentTime.milliseconds;
- RRDeliverEvent(output->pScreen, (xEvent *) &event,
- RROutputPropertyNotifyMask);
- if (prop->current.data)
- xfree(prop->current.data);
- if (prop->pending.data)
- xfree(prop->pending.data);
- xfree(prop);
+ RRDeleteProperty(output, prop);
}
}
@@ -83,39 +126,17 @@ RRCreateOutputProperty(Atom property)
return prop;
}
-static void
-RRDestroyOutputProperty(RRPropertyPtr prop)
-{
- if (prop->valid_values)
- xfree(prop->valid_values);
- if (prop->current.data)
- xfree(prop->current.data);
- if (prop->pending.data)
- xfree(prop->pending.data);
- xfree(prop);
-}
-
void
RRDeleteOutputProperty(RROutputPtr output, Atom property)
{
- RRPropertyPtr prop, *prev;
- xRROutputPropertyNotifyEvent event;
+ RRPropertyRec *prop, **prev;
for (prev = &output->properties; (prop = *prev); prev = &(prop->next))
- if (prop->propertyName == property)
- break;
- if (prop) {
- *prev = prop->next;
- event.type = RREventBase + RRNotify;
- event.subCode = RRNotify_OutputProperty;
- event.output = output->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.timestamp = currentTime.milliseconds;
- RRDeliverEvent(output->pScreen, (xEvent *) &event,
- RROutputPropertyNotifyMask);
- RRDestroyOutputProperty(prop);
- }
+ if (prop->propertyName == property) {
+ *prev = prop->next;
+ RRDeleteProperty(output, prop);
+ return;
+ }
}
int
@@ -124,10 +145,8 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
void *value, Bool sendevent, Bool pending)
{
RRPropertyPtr prop;
- xRROutputPropertyNotifyEvent event;
rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
int size_in_bytes;
- int total_size;
unsigned long total_len;
RRPropertyValuePtr prop_value;
RRPropertyValueRec new_value;
@@ -140,7 +159,7 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
if (!prop) { /* just add to list */
prop = RRCreateOutputProperty(property);
if (!prop)
- return (BadAlloc);
+ return BadAlloc;
add = TRUE;
mode = PropModeReplace;
}
@@ -155,9 +174,9 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
"PropModeReplace" since they will be written over. */
if ((format != prop_value->format) && (mode != PropModeReplace))
- return (BadMatch);
+ return BadMatch;
if ((prop_value->type != type) && (mode != PropModeReplace))
- return (BadMatch);
+ return BadMatch;
new_value = *prop_value;
if (mode == PropModeReplace)
total_len = len;
@@ -167,9 +186,12 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
if (mode == PropModeReplace || len > 0) {
void *new_data = NULL, *old_data = NULL;
- total_size = total_len * size_in_bytes;
- new_value.data = (void *) xalloc(total_size);
- if (!new_value.data && total_size) {
+#ifndef NXAGENT_SERVER
+ new_value.data = xallocarray(total_len, size_in_bytes);
+#else /* !defined(NXAGENT_SERVER) */
+ new_value.data = xalloc(total_len * size_in_bytes);
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!new_value.data && total_len && size_in_bytes) {
if (add)
RRDestroyOutputProperty(prop);
return BadAlloc;
@@ -203,12 +225,12 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
if (pending && pScrPriv->rrOutputSetProperty &&
!pScrPriv->rrOutputSetProperty(output->pScreen, output,
prop->propertyName, &new_value)) {
- if (new_value.data)
- xfree(new_value.data);
- return (BadValue);
+ xfree(new_value.data);
+ if (add)
+ RRDestroyOutputProperty(prop);
+ return BadValue;
}
- if (prop_value->data)
- xfree(prop_value->data);
+ xfree(prop_value->data);
*prop_value = new_value;
}
@@ -225,16 +247,17 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
output->pendingProperties = TRUE;
if (sendevent) {
- event.type = RREventBase + RRNotify;
- event.subCode = RRNotify_OutputProperty;
- event.output = output->id;
- event.state = PropertyNewValue;
- event.atom = prop->propertyName;
- event.timestamp = currentTime.milliseconds;
- RRDeliverEvent(output->pScreen, (xEvent *) &event,
- RROutputPropertyNotifyMask);
- }
- return (Success);
+ xRROutputPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_OutputProperty,
+ .output = output->id,
+ .state = PropertyNewValue,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event);
+ }
+ return Success;
}
Bool
@@ -265,7 +288,7 @@ RRPostPendingProperties(RROutputPtr output)
pending_value->format == current_value->format &&
pending_value->size == current_value->size &&
!memcmp(pending_value->data, current_value->data,
- pending_value->size))
+ pending_value->size * (pending_value->format / 8)))
continue;
if (RRChangeOutputProperty(output, property->propertyName,
@@ -292,13 +315,21 @@ RRPropertyValuePtr
RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending)
{
RRPropertyPtr prop = RRQueryOutputProperty(output, property);
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
if (!prop)
return NULL;
if (pending && prop->is_pending)
return &prop->pending;
- else
+ else {
+#if RANDR_13_INTERFACE
+ /* If we can, try to update the property value first */
+ if (pScrPriv->rrOutputGetProperty)
+ pScrPriv->rrOutputGetProperty(output->pScreen, output,
+ prop->propertyName);
+#endif
return &prop->current;
+ }
}
int
@@ -313,21 +344,31 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property,
if (!prop) {
prop = RRCreateOutputProperty(property);
if (!prop)
- return (BadAlloc);
+ return BadAlloc;
add = TRUE;
}
else if (prop->immutable && !immutable)
- return (BadAccess);
+ return BadAccess;
/*
* ranges must have even number of values
*/
- if (range && (num_values & 1))
+ if (range && (num_values & 1)) {
+ if (add)
+ RRDestroyOutputProperty(prop);
return BadMatch;
+ }
+#ifndef NXAGENT_SERVER
+ new_values = xallocarray(num_values, sizeof(INT32));
+#else /* !defined(NXAGENT_SERVER) */
new_values = xalloc(num_values * sizeof(INT32));
- if (!new_values && num_values)
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!new_values && num_values) {
+ if (add)
+ RRDestroyOutputProperty(prop);
return BadAlloc;
+ }
if (num_values)
memcpy(new_values, values, num_values * sizeof(INT32));
@@ -336,8 +377,7 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property,
* loses any pending values
*/
if (prop->is_pending && !pending) {
- if (prop->pending.data)
- xfree(prop->pending.data);
+ xfree(prop->pending.data);
RRInitOutputPropertyValue(&prop->pending);
}
@@ -345,8 +385,7 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property,
prop->range = range;
prop->immutable = immutable;
prop->num_valid = num_values;
- if (prop->valid_values)
- xfree(prop->valid_values);
+ xfree(prop->valid_values);
prop->valid_values = new_values;
if (add) {
@@ -361,47 +400,51 @@ int
ProcRRListOutputProperties(ClientPtr client)
{
REQUEST(xRRListOutputPropertiesReq);
- Atom *pAtoms = NULL, *temppAtoms;
+ Atom *pAtoms = NULL;
xRRListOutputPropertiesReply rep;
int numProps = 0;
RROutputPtr output;
RRPropertyPtr prop;
+ int n;
REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq);
- output = LookupOutput(client, stuff->output, DixReadAccess);
-
- if (!output)
- return RRErrorBase + BadRROutput;
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
for (prop = output->properties; prop; prop = prop->next)
numProps++;
if (numProps)
- if (!(pAtoms = (Atom *) xalloc(numProps * sizeof(Atom))))
- return (BadAlloc);
+#ifndef NXAGENT_SERVER
+ if (!(pAtoms = xallocarray(numProps, sizeof(Atom))))
+#else /* !defined(NXAGENT_SERVER) */
+ if (!(pAtoms = xalloc(numProps * sizeof(Atom))))
+#endif /* !defined(NXAGENT_SERVER) */
+ return BadAlloc;
- rep.type = X_Reply;
- rep.length = (numProps * sizeof(Atom)) >> 2;
- rep.sequenceNumber = client->sequence;
- rep.nAtoms = numProps;
+ rep = (xRRListOutputPropertiesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(numProps * sizeof(Atom)),
+ .nAtoms = numProps
+ };
if (client->swapped) {
- int n;
-
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swaps(&rep.nAtoms, n);
}
- temppAtoms = pAtoms;
- for (prop = output->properties; prop; prop = prop->next)
- *temppAtoms++ = prop->propertyName;
-
WriteToClient(client, sizeof(xRRListOutputPropertiesReply), (char *) &rep);
+
if (numProps) {
+ /* Copy property name atoms to reply buffer */
+ Atom *temppAtoms = pAtoms;
+ for (prop = output->properties; prop; prop = prop->next)
+ *temppAtoms++ = prop->propertyName;
+
client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
xfree(pAtoms);
}
- return (client->noClientException);
+ return Success;
}
int
@@ -411,33 +454,36 @@ ProcRRQueryOutputProperty(ClientPtr client)
xRRQueryOutputPropertyReply rep;
RROutputPtr output;
RRPropertyPtr prop;
- char *extra;
+ char *extra = NULL;
+ int n;
REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
- output = LookupOutput(client, stuff->output, DixReadAccess);
-
- if (!output)
- return RRErrorBase + BadRROutput;
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
prop = RRQueryOutputProperty(output, stuff->property);
if (!prop)
return BadName;
if (prop->num_valid) {
+#ifndef NXAGENT_SERVER
+ extra = xallocarray(prop->num_valid, sizeof(INT32));
+#else /* !defined(NXAGENT_SERVER) */
extra = xalloc(prop->num_valid * sizeof(INT32));
+#endif /* !defined(NXAGENT_SERVER) */
if (!extra)
return BadAlloc;
}
- rep.type = X_Reply;
- rep.length = prop->num_valid;
- rep.sequenceNumber = client->sequence;
- rep.pending = prop->is_pending;
- rep.range = prop->range;
- rep.immutable = prop->immutable;
- if (client->swapped) {
- int n;
+ rep = (xRRQueryOutputPropertyReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = prop->num_valid,
+ .pending = prop->is_pending,
+ .range = prop->range,
+ .immutable = prop->immutable
+ };
+ if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
}
@@ -449,7 +495,7 @@ ProcRRQueryOutputProperty(ClientPtr client)
extra);
xfree(extra);
}
- return (client->noClientException);
+ return Success;
}
int
@@ -461,15 +507,13 @@ ProcRRConfigureOutputProperty(ClientPtr client)
REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
- output = LookupOutput(client, stuff->output, DixReadAccess);
-
- if (!output)
- return RRErrorBase + BadRROutput;
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
- num_valid = stuff->length - (sizeof(xRRConfigureOutputPropertyReq) >> 2);
- return RRConfigureOutputProperty(output, stuff->property,
- stuff->pending, stuff->range,
- FALSE, num_valid, (INT32 *) (stuff + 1));
+ num_valid =
+ stuff->length - bytes_to_int32(sizeof(xRRConfigureOutputPropertyReq));
+ return RRConfigureOutputProperty(output, stuff->property, stuff->pending,
+ stuff->range, FALSE, num_valid,
+ (INT32 *) (stuff + 1));
}
int
@@ -497,23 +541,21 @@ ProcRRChangeOutputProperty(ClientPtr client)
return BadValue;
}
len = stuff->nUnits;
- if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ if (len > bytes_to_int32((0xffffffff - sizeof(xChangePropertyReq))))
return BadLength;
sizeInBytes = format >> 3;
totalSize = len * sizeInBytes;
REQUEST_FIXED_SIZE(xRRChangeOutputPropertyReq, totalSize);
- output = LookupOutput(client, stuff->output, DixWriteAccess);
- if (!output)
- return RRErrorBase + BadRROutput;
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
if (!ValidAtom(stuff->property)) {
client->errorValue = stuff->property;
- return (BadAtom);
+ return BadAtom;
}
if (!ValidAtom(stuff->type)) {
client->errorValue = stuff->type;
- return (BadAtom);
+ return BadAtom;
}
err = RRChangeOutputProperty(output, stuff->property,
@@ -523,7 +565,7 @@ ProcRRChangeOutputProperty(ClientPtr client)
if (err != Success)
return err;
else
- return client->noClientException;
+ return Success;
}
int
@@ -531,20 +573,30 @@ ProcRRDeleteOutputProperty(ClientPtr client)
{
REQUEST(xRRDeleteOutputPropertyReq);
RROutputPtr output;
+ RRPropertyPtr prop;
REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq);
UpdateCurrentTime();
- output = LookupOutput(client, stuff->output, DixWriteAccess);
- if (!output)
- return RRErrorBase + BadRROutput;
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
if (!ValidAtom(stuff->property)) {
client->errorValue = stuff->property;
- return (BadAtom);
+ return BadAtom;
+ }
+
+ prop = RRQueryOutputProperty(output, stuff->property);
+ if (!prop) {
+ client->errorValue = stuff->property;
+ return BadName;
+ }
+
+ if (prop->immutable) {
+ client->errorValue = stuff->property;
+ return BadAccess;
}
RRDeleteOutputProperty(output, stuff->property);
- return client->noClientException;
+ return Success;
}
int
@@ -556,35 +608,36 @@ ProcRRGetOutputProperty(ClientPtr client)
unsigned long n, len, ind;
RROutputPtr output;
xRRGetOutputPropertyReply reply;
- char *extra;
+ char *extra = NULL;
+ int m;
REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq);
if (stuff->delete)
UpdateCurrentTime();
- output = LookupOutput(client, stuff->output,
- stuff->delete ? DixWriteAccess : DixReadAccess);
- if (!output)
- return RRErrorBase + BadRROutput;
+ VERIFY_RR_OUTPUT(stuff->output, output,
+ stuff->delete ? DixWriteAccess : DixReadAccess);
if (!ValidAtom(stuff->property)) {
client->errorValue = stuff->property;
- return (BadAtom);
+ return BadAtom;
}
if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
client->errorValue = stuff->delete;
- return (BadValue);
+ return BadValue;
}
if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) {
client->errorValue = stuff->type;
- return (BadAtom);
+ return BadAtom;
}
for (prev = &output->properties; (prop = *prev); prev = &prop->next)
if (prop->propertyName == stuff->property)
break;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
+ reply = (xRRGetOutputPropertyReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence
+ };
if (!prop) {
reply.nItems = 0;
reply.length = 0;
@@ -592,25 +645,23 @@ ProcRRGetOutputProperty(ClientPtr client)
reply.propertyType = None;
reply.format = 0;
if (client->swapped) {
- int n;
-
- swaps(&reply.sequenceNumber, n);
- swapl(&reply.length, n);
- swapl(&reply.propertyType, n);
- swapl(&reply.bytesAfter, n);
- swapl(&reply.nItems, n);
+ swaps(&reply.sequenceNumber, m);
+ swapl(&reply.length, m);
+ swapl(&reply.propertyType, m);
+ swapl(&reply.bytesAfter, m);
+ swapl(&reply.nItems, m);
}
- WriteToClient(client, sizeof(xRRGetOutputPropertyReply), &reply);
- return (client->noClientException);
+ WriteToClient(client, sizeof(xRRGetOutputPropertyReply),
+ (char *) &reply);
+ return Success;
}
if (prop->immutable && stuff->delete)
return BadAccess;
- if (stuff->pending && prop->is_pending)
- prop_value = &prop->pending;
- else
- prop_value = &prop->current;
+ prop_value = RRGetOutputProperty(output, stuff->property, stuff->pending);
+ if (!prop_value)
+ return BadAtom;
/* If the request type and actual type don't match. Return the
property information, but not the data. */
@@ -623,16 +674,15 @@ ProcRRGetOutputProperty(ClientPtr client)
reply.nItems = 0;
reply.propertyType = prop_value->type;
if (client->swapped) {
- int n;
-
swaps(&reply.sequenceNumber, n);
swapl(&reply.length, n);
swapl(&reply.propertyType, n);
swapl(&reply.bytesAfter, n);
swapl(&reply.nItems, n);
}
- WriteToClient(client, sizeof(xRRGetOutputPropertyReply), &reply);
- return (client->noClientException);
+ WriteToClient(client, sizeof(xRRGetOutputPropertyReply),
+ (char *) &reply);
+ return Success;
}
/*
@@ -658,7 +708,7 @@ ProcRRGetOutputProperty(ClientPtr client)
}
reply.bytesAfter = n - (ind + len);
reply.format = prop_value->format;
- reply.length = (len + 3) >> 2;
+ reply.length = bytes_to_int32(len);
if (prop_value->format)
reply.nItems = len / (prop_value->format / 8);
else
@@ -666,28 +716,25 @@ ProcRRGetOutputProperty(ClientPtr client)
reply.propertyType = prop_value->type;
if (stuff->delete && (reply.bytesAfter == 0)) {
- xRROutputPropertyNotifyEvent event;
-
- event.type = RREventBase + RRNotify;
- event.subCode = RRNotify_OutputProperty;
- event.output = output->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.timestamp = currentTime.milliseconds;
- RRDeliverEvent(output->pScreen, (xEvent *) &event,
- RROutputPropertyNotifyMask);
+ xRROutputPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_OutputProperty,
+ .output = output->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event);
}
if (client->swapped) {
- int n;
-
swaps(&reply.sequenceNumber, n);
swapl(&reply.length, n);
swapl(&reply.propertyType, n);
swapl(&reply.bytesAfter, n);
swapl(&reply.nItems, n);
}
- WriteToClient(client, sizeof(xGenericReply), &reply);
+ WriteToClient(client, sizeof(xGenericReply), (char *) &reply);
if (len) {
memcpy(extra, (char *) prop_value->data + ind, len);
switch (reply.format) {
@@ -709,5 +756,5 @@ ProcRRGetOutputProperty(ClientPtr client)
*prev = prop->next;
RRDestroyOutputProperty(prop);
}
- return (client->noClientException);
+ return Success;
}
diff --git a/nx-X11/programs/Xserver/randr/rrprovider.c b/nx-X11/programs/Xserver/randr/rrprovider.c
new file mode 100644
index 000000000..b2251b682
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrprovider.c
@@ -0,0 +1,484 @@
+/*
+ * Copyright © 2012 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.
+ *
+ * Authors: Dave Airlie
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+
+RESTYPE RRProviderType;
+
+/*
+ * Initialize provider type error value
+ */
+void
+RRProviderInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RRProviderType, RRErrorBase + BadRRProvider);
+#endif
+}
+
+#define ADD_PROVIDER(_pScreen) do { \
+ pScrPriv = rrGetScrPriv((_pScreen)); \
+ if (pScrPriv->provider) { \
+ providers[count_providers] = pScrPriv->provider->id; \
+ if (client->swapped) \
+ swapl(&providers[count_providers], n); \
+ count_providers++; \
+ } \
+ } while(0)
+
+int
+ProcRRGetProviders(ClientPtr client)
+{
+ REQUEST(xRRGetProvidersReq);
+ xRRGetProvidersReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ int rc;
+ CARD8 *extra;
+ unsigned int extraLen;
+ RRProvider *providers;
+ int total_providers = 0, count_providers = 0;
+#ifndef NXAGENT_SERVER
+ ScreenPtr iter;
+#endif
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRGetProvidersReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv->provider)
+ total_providers++;
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pScrPriv = rrGetScrPriv(iter);
+ total_providers += pScrPriv->provider ? 1 : 0;
+ }
+ xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
+ pScrPriv = rrGetScrPriv(iter);
+ total_providers += pScrPriv->provider ? 1 : 0;
+ }
+ xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ pScrPriv = rrGetScrPriv(iter);
+ total_providers += pScrPriv->provider ? 1 : 0;
+ }
+#endif
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv)
+ {
+ rep = (xRRGetProvidersReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = currentTime.milliseconds,
+ .nProviders = 0
+ };
+ extra = NULL;
+ extraLen = 0;
+ } else {
+ rep = (xRRGetProvidersReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .nProviders = total_providers,
+ .length = total_providers
+ };
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = xalloc(extraLen);
+ if (!extra)
+ return BadAlloc;
+ } else
+ extra = NULL;
+
+ providers = (RRProvider *) extra;
+ ADD_PROVIDER(pScreen);
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ ADD_PROVIDER(iter);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
+ ADD_PROVIDER(iter);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ ADD_PROVIDER(iter);
+ }
+#endif
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swaps(&rep.nProviders, n);
+ }
+ WriteToClient(client, sizeof(xRRGetProvidersReply), (char *) &rep);
+ if (extraLen)
+ {
+ WriteToClient(client, extraLen, (char *) extra);
+ xfree(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRGetProviderInfo(ClientPtr client)
+{
+ REQUEST(xRRGetProviderInfoReq);
+ xRRGetProviderInfoReply rep;
+ rrScrPrivPtr pScrPriv;
+#ifndef NXAGENT_SERVER
+ rrScrPrivPtr pScrProvPriv;
+#endif
+ RRProviderPtr provider;
+ ScreenPtr pScreen;
+ CARD8 *extra;
+ unsigned int extraLen = 0;
+ RRCrtc *crtcs;
+ RROutput *outputs;
+ int i;
+ char *name;
+#ifndef NXAGENT_SERVER
+ ScreenPtr provscreen;
+#endif
+ RRProvider *providers;
+ uint32_t *prov_cap;
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRGetProviderInfoReq);
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ rep = (xRRGetProviderInfoReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .capabilities = provider->capabilities,
+ .nameLength = provider->nameLength,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .nCrtcs = pScrPriv->numCrtcs,
+ .nOutputs = pScrPriv->numOutputs,
+ .nAssociatedProviders = 0
+ };
+
+ /* count associated providers */
+ if (provider->offload_sink)
+ rep.nAssociatedProviders++;
+ if (provider->output_source)
+ rep.nAssociatedProviders++;
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head)
+ rep.nAssociatedProviders++;
+ xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head)
+ rep.nAssociatedProviders++;
+#endif
+
+ rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs +
+ (rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength));
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = xalloc(extraLen);
+ if (!extra)
+ return BadAlloc;
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *) extra;
+ outputs = (RROutput *) (crtcs + rep.nCrtcs);
+ providers = (RRProvider *) (outputs + rep.nOutputs);
+ prov_cap = (unsigned int *) (providers + rep.nAssociatedProviders);
+ name = (char *) (prov_cap + rep.nAssociatedProviders);
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ crtcs[i] = pScrPriv->crtcs[i]->id;
+ if (client->swapped)
+ swapl(&crtcs[i], n);
+ }
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ outputs[i] = pScrPriv->outputs[i]->id;
+ if (client->swapped)
+ swapl(&outputs[i], n);
+ }
+
+ i = 0;
+ if (provider->offload_sink) {
+ providers[i] = provider->offload_sink->id;
+ if (client->swapped)
+ swapl(&providers[i], n);
+ prov_cap[i] = RR_Capability_SinkOffload;
+ if (client->swapped)
+ swapl(&prov_cap[i], n);
+ i++;
+ }
+ if (provider->output_source) {
+ providers[i] = provider->output_source->id;
+ if (client->swapped)
+ swapl(&providers[i], n);
+ prov_cap[i] = RR_Capability_SourceOutput;
+ swapl(&prov_cap[i], n);
+ i++;
+ }
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) {
+ pScrProvPriv = rrGetScrPriv(provscreen);
+ providers[i] = pScrProvPriv->provider->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SinkOutput;
+ if (client->swapped)
+ swapl(&prov_cap[i]);
+ i++;
+ }
+ xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) {
+ pScrProvPriv = rrGetScrPriv(provscreen);
+ providers[i] = pScrProvPriv->provider->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SourceOffload;
+ if (client->swapped)
+ swapl(&prov_cap[i]);
+ i++;
+ }
+#endif
+ memcpy(name, provider->name, rep.nameLength);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.capabilities, n);
+ swaps(&rep.nCrtcs, n);
+ swaps(&rep.nOutputs, n);
+ swaps(&rep.nameLength, n);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderInfoReply), (char *) &rep);
+ if (extraLen)
+ {
+ WriteToClient(client, extraLen, (char *) extra);
+ xfree(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRSetProviderOutputSource(ClientPtr client)
+{
+ REQUEST(xRRSetProviderOutputSourceReq);
+ rrScrPrivPtr pScrPriv;
+ RRProviderPtr provider, source_provider = NULL;
+ ScreenPtr pScreen;
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ if (!(provider->capabilities & RR_Capability_SinkOutput))
+ return BadValue;
+
+ if (stuff->source_provider) {
+ VERIFY_RR_PROVIDER(stuff->source_provider, source_provider, DixReadAccess);
+
+ if (!(source_provider->capabilities & RR_Capability_SourceOutput))
+ return BadValue;
+ }
+
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider);
+
+ provider->changed = TRUE;
+ RRSetChanged(pScreen);
+
+ RRTellChanged(pScreen);
+
+ return Success;
+}
+
+int
+ProcRRSetProviderOffloadSink(ClientPtr client)
+{
+ REQUEST(xRRSetProviderOffloadSinkReq);
+ rrScrPrivPtr pScrPriv;
+ RRProviderPtr provider, sink_provider = NULL;
+ ScreenPtr pScreen;
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+ if (!(provider->capabilities & RR_Capability_SourceOffload))
+ return BadValue;
+#ifndef NXAGENT_SERVER
+ if (!provider->pScreen->isGPU)
+ return BadValue;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (stuff->sink_provider) {
+ VERIFY_RR_PROVIDER(stuff->sink_provider, sink_provider, DixReadAccess);
+ if (!(sink_provider->capabilities & RR_Capability_SinkOffload))
+ return BadValue;
+ }
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider);
+
+ provider->changed = TRUE;
+ RRSetChanged(pScreen);
+
+ RRTellChanged(pScreen);
+
+ return Success;
+}
+
+RRProviderPtr
+RRProviderCreate(ScreenPtr pScreen, const char *name,
+ int nameLength)
+{
+ RRProviderPtr provider;
+ rrScrPrivPtr pScrPriv;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ provider = xcalloc(1, sizeof(RRProviderRec) + nameLength + 1);
+ if (!provider)
+ return NULL;
+
+ provider->id = FakeClientID(0);
+ provider->pScreen = pScreen;
+ provider->name = (char *) (provider + 1);
+ provider->nameLength = nameLength;
+ memcpy(provider->name, name, nameLength);
+ provider->name[nameLength] = '\0';
+ provider->changed = FALSE;
+
+ if (!AddResource(provider->id, RRProviderType, (void *) provider))
+ return NULL;
+ pScrPriv->provider = provider;
+ return provider;
+}
+
+/*
+ * Destroy a provider at shutdown
+ */
+void
+RRProviderDestroy(RRProviderPtr provider)
+{
+ FreeResource(provider->id, 0);
+}
+
+void
+RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities)
+{
+ provider->capabilities = capabilities;
+}
+
+static int
+RRProviderDestroyResource(void *value, XID pid)
+{
+ RRProviderPtr provider = (RRProviderPtr) value;
+ ScreenPtr pScreen = provider->pScreen;
+
+ if (pScreen)
+ {
+ rrScrPriv(pScreen);
+
+ if (pScrPriv->rrProviderDestroy)
+ (*pScrPriv->rrProviderDestroy) (pScreen, provider);
+ pScrPriv->provider = NULL;
+ }
+ xfree(provider);
+ return 1;
+}
+
+Bool
+RRProviderInit(void)
+{
+ RRProviderType = CreateNewResourceType(RRProviderDestroyResource
+#ifndef NXAGENT_SERVER
+ , "Provider"
+#endif /* !defined(NXAGENT_SERVER) */
+ );
+ if (!RRProviderType)
+ return FALSE;
+
+ return TRUE;
+}
+
+extern _X_EXPORT Bool
+RRProviderLookup(XID id, RRProviderPtr * provider_p)
+{
+#ifndef NXAGENT_SERVER
+ int rc = dixLookupResourceByType((void **) provider_p, id,
+ RRProviderType, NullClient, DixReadAccess);
+ if (rc == Success)
+ return TRUE;
+#else /* !defined(NXAGENT_SERVER) */
+ provider_p = (RRProviderPtr *) LookupIDByType(id, RREventType);
+ if (provider_p)
+ return TRUE;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ return FALSE;
+}
+
+void
+RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+
+ xRRProviderChangeNotifyEvent pe = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_ProviderChange,
+#ifdef NXAGENT_SERVER
+ .sequenceNumber = client->sequence,
+#endif
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id,
+ .provider = provider->id
+ };
+
+ WriteEventsToClient(client, 1, (xEvent *) &pe);
+}
diff --git a/nx-X11/programs/Xserver/randr/rrproviderproperty.c b/nx-X11/programs/Xserver/randr/rrproviderproperty.c
new file mode 100644
index 000000000..a68a94ff2
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrproviderproperty.c
@@ -0,0 +1,752 @@
+/*
+ * 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"
+#include "propertyst.h"
+#include "swaprep.h"
+
+static int
+DeliverPropertyEvent(WindowPtr pWin, void *value)
+{
+ xRRProviderPropertyNotifyEvent *event = value;
+ RREventPtr *pHead, pRREvent;
+
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixReadAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (!(pRREvent->mask & RRProviderPropertyNotifyMask))
+ continue;
+
+ event->window = pRREvent->window->drawable.id;
+ WriteEventsToClient(pRREvent->client, 1, (xEvent *) event);
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static void
+RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
+{
+ if (!(dispatchException & (DE_RESET | DE_TERMINATE)))
+ WalkTree(pScreen, DeliverPropertyEvent, event);
+}
+
+static void
+RRDestroyProviderProperty(RRPropertyPtr prop)
+{
+ xfree(prop->valid_values);
+ xfree(prop->current.data);
+ xfree(prop->pending.data);
+ xfree(prop);
+}
+
+static void
+RRDeleteProperty(RRProviderRec * provider, RRPropertyRec * prop)
+{
+ xRRProviderPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_ProviderProperty,
+ .provider = provider->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+
+ RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event);
+
+ RRDestroyProviderProperty(prop);
+}
+
+void
+RRDeleteAllProviderProperties(RRProviderPtr provider)
+{
+ RRPropertyPtr prop, next;
+
+ for (prop = provider->properties; prop; prop = next) {
+ next = prop->next;
+ RRDeleteProperty(provider, prop);
+ }
+}
+
+static void
+RRInitProviderPropertyValue(RRPropertyValuePtr property_value)
+{
+ property_value->type = None;
+ property_value->format = 0;
+ property_value->size = 0;
+ property_value->data = NULL;
+}
+
+static RRPropertyPtr
+RRCreateProviderProperty(Atom property)
+{
+ RRPropertyPtr prop;
+
+ prop = (RRPropertyPtr) xalloc(sizeof(RRPropertyRec));
+ if (!prop)
+ return NULL;
+ prop->next = NULL;
+ prop->propertyName = property;
+ prop->is_pending = FALSE;
+ prop->range = FALSE;
+ prop->immutable = FALSE;
+ prop->num_valid = 0;
+ prop->valid_values = NULL;
+ RRInitProviderPropertyValue(&prop->current);
+ RRInitProviderPropertyValue(&prop->pending);
+ return prop;
+}
+
+void
+RRDeleteProviderProperty(RRProviderPtr provider, Atom property)
+{
+ RRPropertyRec *prop, **prev;
+
+ for (prev = &provider->properties; (prop = *prev); prev = &(prop->next))
+ if (prop->propertyName == property) {
+ *prev = prop->next;
+ RRDeleteProperty(provider, prop);
+ return;
+ }
+}
+
+int
+RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
+ int format, int mode, unsigned long len,
+ void *value, Bool sendevent, Bool pending)
+{
+ RRPropertyPtr prop;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(provider->pScreen);
+ int size_in_bytes;
+ int total_size;
+ unsigned long total_len;
+ RRPropertyValuePtr prop_value;
+ RRPropertyValueRec new_value;
+ Bool add = FALSE;
+
+ size_in_bytes = format >> 3;
+
+ /* first see if property already exists */
+ prop = RRQueryProviderProperty(provider, property);
+ if (!prop) { /* just add to list */
+ prop = RRCreateProviderProperty(property);
+ if (!prop)
+ return BadAlloc;
+ add = TRUE;
+ mode = PropModeReplace;
+ }
+ if (pending && prop->is_pending)
+ prop_value = &prop->pending;
+ else
+ prop_value = &prop->current;
+
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != prop_value->format) && (mode != PropModeReplace))
+ return BadMatch;
+ if ((prop_value->type != type) && (mode != PropModeReplace))
+ return BadMatch;
+ new_value = *prop_value;
+ if (mode == PropModeReplace)
+ total_len = len;
+ else
+ total_len = prop_value->size + len;
+
+ if (mode == PropModeReplace || len > 0) {
+ void *new_data = NULL, *old_data = NULL;
+
+ total_size = total_len * size_in_bytes;
+ new_value.data = (void *) xalloc(total_size);
+ if (!new_value.data && total_size) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ return BadAlloc;
+ }
+ new_value.size = len;
+ new_value.type = type;
+ new_value.format = format;
+
+ switch (mode) {
+ case PropModeReplace:
+ new_data = new_value.data;
+ old_data = NULL;
+ break;
+ case PropModeAppend:
+ new_data = (void *) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ old_data = new_value.data;
+ break;
+ case PropModePrepend:
+ new_data = new_value.data;
+ old_data = (void *) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ break;
+ }
+ if (new_data)
+ memcpy((char *) new_data, (char *) value, len * size_in_bytes);
+ if (old_data)
+ memcpy((char *) old_data, (char *) prop_value->data,
+ prop_value->size * size_in_bytes);
+
+ if (pending && pScrPriv->rrProviderSetProperty &&
+ !pScrPriv->rrProviderSetProperty(provider->pScreen, provider,
+ prop->propertyName, &new_value)) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ xfree(new_value.data);
+ return BadValue;
+ }
+ xfree(prop_value->data);
+ *prop_value = new_value;
+ }
+
+ else if (len == 0) {
+ /* do nothing */
+ }
+
+ if (add) {
+ prop->next = provider->properties;
+ provider->properties = prop;
+ }
+
+ if (pending && prop->is_pending)
+ provider->pendingProperties = TRUE;
+
+ if (sendevent) {
+ xRRProviderPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_ProviderProperty,
+ .provider = provider->id,
+ .state = PropertyNewValue,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event);
+ }
+ return Success;
+}
+
+Bool
+RRPostProviderPendingProperties(RRProviderPtr provider)
+{
+ RRPropertyValuePtr pending_value;
+ RRPropertyValuePtr current_value;
+ RRPropertyPtr property;
+ Bool ret = TRUE;
+
+ if (!provider->pendingProperties)
+ return TRUE;
+
+ provider->pendingProperties = FALSE;
+ for (property = provider->properties; property; property = property->next) {
+ /* Skip non-pending properties */
+ if (!property->is_pending)
+ continue;
+
+ pending_value = &property->pending;
+ current_value = &property->current;
+
+ /*
+ * If the pending and current values are equal, don't mark it
+ * as changed (which would deliver an event)
+ */
+ if (pending_value->type == current_value->type &&
+ pending_value->format == current_value->format &&
+ pending_value->size == current_value->size &&
+ !memcmp(pending_value->data, current_value->data,
+ pending_value->size * (pending_value->format / 8)))
+ continue;
+
+ if (RRChangeProviderProperty(provider, property->propertyName,
+ pending_value->type, pending_value->format,
+ PropModeReplace, pending_value->size,
+ pending_value->data, TRUE, FALSE) != Success)
+ ret = FALSE;
+ }
+ return ret;
+}
+
+RRPropertyPtr
+RRQueryProviderProperty(RRProviderPtr provider, Atom property)
+{
+ RRPropertyPtr prop;
+
+ for (prop = provider->properties; prop; prop = prop->next)
+ if (prop->propertyName == property)
+ return prop;
+ return NULL;
+}
+
+RRPropertyValuePtr
+RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending)
+{
+ RRPropertyPtr prop = RRQueryProviderProperty(provider, property);
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(provider->pScreen);
+
+ if (!prop)
+ return NULL;
+ if (pending && prop->is_pending)
+ return &prop->pending;
+ else {
+#if RANDR_13_INTERFACE
+ /* If we can, try to update the property value first */
+ if (pScrPriv->rrProviderGetProperty)
+ pScrPriv->rrProviderGetProperty(provider->pScreen, provider,
+ prop->propertyName);
+#endif
+ return &prop->current;
+ }
+}
+
+int
+RRConfigureProviderProperty(RRProviderPtr provider, Atom property,
+ Bool pending, Bool range, Bool immutable,
+ int num_values, INT32 *values)
+{
+ RRPropertyPtr prop = RRQueryProviderProperty(provider, property);
+ Bool add = FALSE;
+ INT32 *new_values;
+
+ if (!prop) {
+ prop = RRCreateProviderProperty(property);
+ if (!prop)
+ return BadAlloc;
+ add = TRUE;
+ }
+ else if (prop->immutable && !immutable)
+ return BadAccess;
+
+ /*
+ * ranges must have even number of values
+ */
+ if (range && (num_values & 1)) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ return BadMatch;
+ }
+
+#ifndef NXAGENT_SERVER
+ new_values = xallocarray(num_values, sizeof(INT32));
+#else /* !defined(NXAGENT_SERVER) */
+ new_values = xalloc(num_values * sizeof(INT32));
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (!new_values && num_values) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ return BadAlloc;
+ }
+ if (num_values)
+ memcpy(new_values, values, num_values * sizeof(INT32));
+
+ /*
+ * Property moving from pending to non-pending
+ * loses any pending values
+ */
+ if (prop->is_pending && !pending) {
+ xfree(prop->pending.data);
+ RRInitProviderPropertyValue(&prop->pending);
+ }
+
+ prop->is_pending = pending;
+ prop->range = range;
+ prop->immutable = immutable;
+ prop->num_valid = num_values;
+ xfree(prop->valid_values);
+ prop->valid_values = new_values;
+
+ if (add) {
+ prop->next = provider->properties;
+ provider->properties = prop;
+ }
+
+ return Success;
+}
+
+int
+ProcRRListProviderProperties(ClientPtr client)
+{
+ REQUEST(xRRListProviderPropertiesReq);
+ Atom *pAtoms = NULL, *temppAtoms;
+ xRRListProviderPropertiesReply rep;
+ int numProps = 0;
+ RRProviderPtr provider;
+ RRPropertyPtr prop;
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRListProviderPropertiesReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ for (prop = provider->properties; prop; prop = prop->next)
+ numProps++;
+ if (numProps)
+#ifndef NXAGENT_SERVER
+ if (!(pAtoms = xallocarray(numProps, sizeof(Atom))))
+#else /* !defined(NXAGENT_SERVER) */
+ if (!(pAtoms = xalloc(numProps * sizeof(Atom))))
+#endif /* !defined(NXAGENT_SERVER) */
+ return BadAlloc;
+
+ rep = (xRRListProviderPropertiesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(numProps * sizeof(Atom)),
+ .nAtoms = numProps
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.nAtoms, n);
+ }
+ temppAtoms = pAtoms;
+ for (prop = provider->properties; prop; prop = prop->next)
+ *temppAtoms++ = prop->propertyName;
+
+ WriteToClient(client, sizeof(xRRListProviderPropertiesReply),
+ (char *) &rep);
+ if (numProps) {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ xfree(pAtoms);
+ }
+ return Success;
+}
+
+int
+ProcRRQueryProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRQueryProviderPropertyReq);
+ xRRQueryProviderPropertyReply rep;
+ RRProviderPtr provider;
+ RRPropertyPtr prop;
+ char *extra = NULL;
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRQueryProviderPropertyReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ prop = RRQueryProviderProperty(provider, stuff->property);
+ if (!prop)
+ return BadName;
+
+ if (prop->num_valid) {
+#ifndef NXAGENT_SERVER
+ extra = xallocarray(prop->num_valid, sizeof(INT32));
+#else /* !defined(NXAGENT_SERVER) */
+ extra = xalloc(prop->num_valid * sizeof(INT32));
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!extra)
+ return BadAlloc;
+ }
+ rep = (xRRQueryProviderPropertyReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = prop->num_valid,
+ .pending = prop->is_pending,
+ .range = prop->range,
+ .immutable = prop->immutable
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xRRQueryProviderPropertyReply), (char *) &rep);
+ if (prop->num_valid) {
+ memcpy(extra, prop->valid_values, prop->num_valid * sizeof(INT32));
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32),
+ extra);
+ xfree(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRConfigureProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRConfigureProviderPropertyReq);
+ RRProviderPtr provider;
+ int num_valid;
+
+ REQUEST_AT_LEAST_SIZE(xRRConfigureProviderPropertyReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ num_valid =
+ stuff->length - bytes_to_int32(sizeof(xRRConfigureProviderPropertyReq));
+ return RRConfigureProviderProperty(provider, stuff->property, stuff->pending,
+ stuff->range, FALSE, num_valid,
+ (INT32 *) (stuff + 1));
+}
+
+int
+ProcRRChangeProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRChangeProviderPropertyReq);
+ RRProviderPtr provider;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+
+ REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend)) {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32)) {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > bytes_to_int32((0xffffffff - sizeof(xChangePropertyReq))))
+ return BadLength;
+ sizeInBytes = format >> 3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xRRChangeProviderPropertyReq, totalSize);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+ if (!ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return BadAtom;
+ }
+
+ err = RRChangeProviderProperty(provider, stuff->property,
+ stuff->type, (int) format,
+ (int) mode, len, (void *) &stuff[1], TRUE,
+ TRUE);
+ if (err != Success)
+ return err;
+ else
+ return Success;
+}
+
+int
+ProcRRDeleteProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRDeleteProviderPropertyReq);
+ RRProviderPtr provider;
+ RRPropertyPtr prop;
+
+ REQUEST_SIZE_MATCH(xRRDeleteProviderPropertyReq);
+ UpdateCurrentTime();
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+
+ prop = RRQueryProviderProperty(provider, stuff->property);
+ if (!prop) {
+ client->errorValue = stuff->property;
+ return BadName;
+ }
+
+ if (prop->immutable) {
+ client->errorValue = stuff->property;
+ return BadAccess;
+ }
+
+ RRDeleteProviderProperty(provider, stuff->property);
+ return Success;
+}
+
+int
+ProcRRGetProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRGetProviderPropertyReq);
+ RRPropertyPtr prop, *prev;
+ RRPropertyValuePtr prop_value;
+ unsigned long n, len, ind;
+ RRProviderPtr provider;
+ xRRGetProviderPropertyReply reply = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence
+ };
+ char *extra = NULL;
+
+ REQUEST_SIZE_MATCH(xRRGetProviderPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ VERIFY_RR_PROVIDER(stuff->provider, provider,
+ stuff->delete ? DixWriteAccess : DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
+ client->errorValue = stuff->delete;
+ return BadValue;
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return BadAtom;
+ }
+
+ for (prev = &provider->properties; (prop = *prev); prev = &prop->next)
+ if (prop->propertyName == stuff->property)
+ break;
+
+ if (!prop) {
+ reply.nItems = 0;
+ reply.length = 0;
+ reply.bytesAfter = 0;
+ reply.propertyType = None;
+ reply.format = 0;
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber, n);
+ swapl(&reply.length, n);
+ swapl(&reply.propertyType, n);
+ swapl(&reply.bytesAfter, n);
+ swapl(&reply.nItems, n);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderPropertyReply),
+ (char *) &reply);
+ return Success;
+ }
+
+ if (prop->immutable && stuff->delete)
+ return BadAccess;
+
+ prop_value = RRGetProviderProperty(provider, stuff->property, stuff->pending);
+ if (!prop_value)
+ return BadAtom;
+
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != prop_value->type) && (stuff->type != AnyPropertyType))
+ ) {
+ reply.bytesAfter = prop_value->size;
+ reply.format = prop_value->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = prop_value->type;
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber, n);
+ swapl(&reply.length, n);
+ swapl(&reply.propertyType, n);
+ swapl(&reply.bytesAfter, n);
+ swapl(&reply.nItems, n);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderPropertyReply),
+ (char *) &reply);
+ return Success;
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (prop_value->format / 8) * prop_value->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind) {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ if (len) {
+ extra = xalloc(len);
+ if (!extra)
+ return BadAlloc;
+ }
+ reply.bytesAfter = n - (ind + len);
+ reply.format = prop_value->format;
+ reply.length = bytes_to_int32(len);
+ if (prop_value->format)
+ reply.nItems = len / (prop_value->format / 8);
+ else
+ reply.nItems = 0;
+ reply.propertyType = prop_value->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ xRRProviderPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_ProviderProperty,
+ .provider = provider->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event);
+ }
+
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber, n);
+ swapl(&reply.length, n);
+ swapl(&reply.propertyType, n);
+ swapl(&reply.bytesAfter, n);
+ swapl(&reply.nItems, n);
+ }
+ WriteToClient(client, sizeof(xGenericReply), (char *) &reply);
+ if (len) {
+ memcpy(extra, (char *) prop_value->data + ind, len);
+ switch (reply.format) {
+ case 32:
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+ break;
+ case 16:
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
+ break;
+ default:
+ client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
+ break;
+ }
+ WriteSwappedDataToClient(client, len, extra);
+ xfree(extra);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0)) { /* delete the Property */
+ *prev = prop->next;
+ RRDestroyProviderProperty(prop);
+ }
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/randr/rrscreen.c b/nx-X11/programs/Xserver/randr/rrscreen.c
index 458416c1f..af54d66f5 100644
--- a/nx-X11/programs/Xserver/randr/rrscreen.c
+++ b/nx-X11/programs/Xserver/randr/rrscreen.c
@@ -39,10 +39,6 @@
#include "randrstr.h"
-extern char *ConnectionInfo;
-
-static int padlength[4] = { 0, 3, 2, 1 };
-
static CARD16
RR10CurrentSizeID(ScreenPtr pScreen);
@@ -65,8 +61,7 @@ RREditConnectionInfo(ScreenPtr pScreen)
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof(xConnSetup);
formats = (xPixmapFormat *) ((char *) vendor +
- connSetup->nbytesVendor +
- padlength[connSetup->nbytesVendor & 3]);
+ pad_to_int32(connSetup->nbytesVendor));
root = (xWindowRoot *) ((char *) formats +
sizeof(xPixmapFormat) *
screenInfo.numPixmapFormats);
@@ -89,21 +84,21 @@ RREditConnectionInfo(ScreenPtr pScreen)
void
RRSendConfigNotify(ScreenPtr pScreen)
{
- WindowPtr pWin = WindowTable[pScreen->myNum];
- xEvent event;
-
+ WindowPtr pWin = pScreen->root;
+ xEvent event = {
+ .u.configureNotify.window = pWin->drawable.id,
+ .u.configureNotify.aboveSibling = None,
+ .u.configureNotify.x = 0,
+ .u.configureNotify.y = 0,
+
+ /* XXX xinerama stuff ? */
+
+ .u.configureNotify.width = pWin->drawable.width,
+ .u.configureNotify.height = pWin->drawable.height,
+ .u.configureNotify.borderWidth = wBorderWidth(pWin),
+ .u.configureNotify.override = pWin->overrideRedirect
+ };
event.u.u.type = ConfigureNotify;
- event.u.configureNotify.window = pWin->drawable.id;
- event.u.configureNotify.aboveSibling = None;
- event.u.configureNotify.x = 0;
- event.u.configureNotify.y = 0;
-
- /* XXX xinerama stuff ? */
-
- event.u.configureNotify.width = pWin->drawable.width;
- event.u.configureNotify.height = pWin->drawable.height;
- event.u.configureNotify.borderWidth = wBorderWidth(pWin);
- event.u.configureNotify.override = pWin->overrideRedirect;
DeliverEvents(pWin, &event, 1, NullWindow);
}
@@ -111,25 +106,23 @@ void
RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
{
rrScrPriv(pScreen);
- xRRScreenChangeNotifyEvent se;
RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL;
- WindowPtr pRoot = WindowTable[pScreen->myNum];
-
- se.type = RRScreenChangeNotify + RREventBase;
- se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0);
- se.timestamp = pScrPriv->lastSetTime.milliseconds;
- se.sequenceNumber = client->sequence;
- se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
- se.root = pRoot->drawable.id;
- se.window = pWin->drawable.id;
-#ifdef RENDER
- se.subpixelOrder = PictureGetSubpixelOrder(pScreen);
-#else
- se.subpixelOrder = SubPixelUnknown;
+ WindowPtr pRoot = pScreen->root;
+
+ xRRScreenChangeNotifyEvent se = {
+ .type = RRScreenChangeNotify + RREventBase,
+#ifdef NXAGENT_SERVER
+ .sequenceNumber = client->sequence,
#endif
+ .rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0),
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .root = pRoot->drawable.id,
+ .window = pWin->drawable.id,
+ .subpixelOrder = PictureGetSubpixelOrder(pScreen),
- se.sequenceNumber = client->sequence;
- se.sizeID = RR10CurrentSizeID(pScreen);
+ .sizeID = RR10CurrentSizeID(pScreen)
+ };
if (se.rotation & (RR_Rotate_90 | RR_Rotate_270)) {
se.widthInPixels = pScreen->height;
@@ -144,7 +137,7 @@ RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
se.heightInMillimeters = pScreen->mmHeight;
}
- WriteEventsToClient(client, 1, (xEvent *) &se);
+ WriteEventsToClient(client, 1, (xEvent *) (char *) &se);
}
/*
@@ -170,7 +163,7 @@ RRScreenSizeNotify(ScreenPtr pScreen)
pScrPriv->height = pScreen->height;
pScrPriv->mmWidth = pScreen->mmWidth;
pScrPriv->mmHeight = pScreen->mmHeight;
- pScrPriv->changed = TRUE;
+ RRSetChanged(pScreen);
/* pScrPriv->sizeChanged = TRUE; */
RRTellChanged(pScreen);
@@ -219,27 +212,31 @@ ProcRRGetScreenSizeRange(ClientPtr client)
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
int rc;
+ int n;
REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq);
#ifndef NXAGENT_SERVER
- rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
+
if (rc != Success)
return rc;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
- rep.type = X_Reply;
- rep.pad = 0;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
+ rep = (xRRGetScreenSizeRangeReply) {
+ .type = X_Reply,
+ .pad = 0,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
if (pScrPriv) {
- if (!RRGetInfo(pScreen))
+ if (!RRGetInfo(pScreen, FALSE))
return BadAlloc;
rep.minWidth = pScrPriv->minWidth;
rep.minHeight = pScrPriv->minHeight;
@@ -251,8 +248,6 @@ ProcRRGetScreenSizeRange(ClientPtr client)
rep.maxHeight = rep.minHeight = pScreen->height;
}
if (client->swapped) {
- int n;
-
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swaps(&rep.minWidth, n);
@@ -261,7 +256,7 @@ ProcRRGetScreenSizeRange(ClientPtr client)
swaps(&rep.maxHeight, n);
}
WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *) &rep);
- return (client->noClientException);
+ return Success;
}
int
@@ -275,7 +270,7 @@ ProcRRSetScreenSize(ClientPtr client)
REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
#ifndef NXAGENT_SERVER
- rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
@@ -285,6 +280,9 @@ ProcRRSetScreenSize(ClientPtr client)
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
+ if (!pScrPriv)
+ return BadMatch;
+
if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) {
client->errorValue = stuff->width;
return BadValue;
@@ -326,8 +324,194 @@ ProcRRSetScreenSize(ClientPtr client)
return Success;
}
-int
-ProcRRGetScreenResources(ClientPtr client)
+
+#define update_totals(gpuscreen, pScrPriv) do { \
+ total_crtcs += pScrPriv->numCrtcs; \
+ total_outputs += pScrPriv->numOutputs; \
+ modes = RRModesForScreen(gpuscreen, &num_modes); \
+ if (!modes) \
+ return BadAlloc; \
+ for (j = 0; j < num_modes; j++) \
+ total_name_len += modes[j]->mode.nameLength; \
+ total_modes += num_modes; \
+ xfree(modes); \
+} while(0)
+
+static inline void
+swap_modeinfos(xRRModeInfo * modeinfos, int i)
+{
+ int n;
+
+ swapl(&modeinfos[i].id, n);
+ swaps(&modeinfos[i].width, n);
+ swaps(&modeinfos[i].height, n);
+ swapl(&modeinfos[i].dotClock, n);
+ swaps(&modeinfos[i].hSyncStart, n);
+ swaps(&modeinfos[i].hSyncEnd, n);
+ swaps(&modeinfos[i].hTotal, n);
+ swaps(&modeinfos[i].hSkew, n);
+ swaps(&modeinfos[i].vSyncStart, n);
+ swaps(&modeinfos[i].vSyncEnd, n);
+ swaps(&modeinfos[i].vTotal, n);
+ swaps(&modeinfos[i].nameLength, n);
+ swapl(&modeinfos[i].modeFlags, n);
+}
+
+#define update_arrays(gpuscreen, pScrPriv, primary_crtc, has_primary) do { \
+ for (j = 0; j < pScrPriv->numCrtcs; j++) { \
+ if (has_primary && \
+ primary_crtc == pScrPriv->crtcs[j]) { \
+ has_primary = 0; \
+ continue; \
+ }\
+ crtcs[crtc_count] = pScrPriv->crtcs[j]->id; \
+ if (client->swapped) \
+ swapl(&crtcs[crtc_count], n); \
+ crtc_count++; \
+ } \
+ for (j = 0; j < pScrPriv->numOutputs; j++) { \
+ outputs[output_count] = pScrPriv->outputs[j]->id; \
+ if (client->swapped) \
+ swapl(&outputs[output_count], n); \
+ output_count++; \
+ } \
+ { \
+ RRModePtr mode; \
+ modes = RRModesForScreen(gpuscreen, &num_modes); \
+ for (j = 0; j < num_modes; j++) { \
+ mode = modes[j]; \
+ modeinfos[mode_count] = mode->mode; \
+ if (client->swapped) { \
+ swap_modeinfos(modeinfos, mode_count); \
+ } \
+ memcpy(names, mode->name, mode->mode.nameLength); \
+ names += mode->mode.nameLength; \
+ mode_count++; \
+ } \
+ xfree(modes); \
+ } \
+ } while (0)
+
+#ifndef NXAGENT_SERVER
+static int
+rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
+{
+ int j;
+ int total_crtcs, total_outputs, total_modes, total_name_len;
+ int crtc_count, output_count, mode_count;
+ ScreenPtr iter;
+ rrScrPrivPtr pScrPriv;
+ int num_modes;
+ RRModePtr *modes;
+ xRRGetScreenResourcesReply rep;
+ unsigned long extraLen;
+ CARD8 *extra;
+ RRCrtc *crtcs;
+ RRCrtcPtr primary_crtc = NULL;
+ RROutput *outputs;
+ xRRModeInfo *modeinfos;
+ CARD8 *names;
+ int has_primary = 0;
+ int n;
+
+ /* we need to iterate all the GPU masters and all their output slaves */
+ total_crtcs = 0;
+ total_outputs = 0;
+ total_modes = 0;
+ total_name_len = 0;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (query && pScrPriv)
+ if (!RRGetInfo(pScreen, query))
+ return BadAlloc;
+
+ update_totals(pScreen, pScrPriv);
+
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pScrPriv = rrGetScrPriv(iter);
+
+ if (query)
+ if (!RRGetInfo(iter, query))
+ return BadAlloc;
+ update_totals(iter, pScrPriv);
+ }
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ rep = (xRRGetScreenResourcesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .nCrtcs = total_crtcs,
+ .nOutputs = total_outputs,
+ .nModes = total_modes,
+ .nbytesNames = total_name_len
+ };
+
+ rep.length = (total_crtcs + total_outputs +
+ total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) +
+ bytes_to_int32(total_name_len));
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = xalloc(extraLen);
+ if (!extra) {
+ return BadAlloc;
+ }
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *) extra;
+ outputs = (RROutput *) (crtcs + total_crtcs);
+ modeinfos = (xRRModeInfo *) (outputs + total_outputs);
+ names = (CARD8 *) (modeinfos + total_modes);
+
+ crtc_count = 0;
+ output_count = 0;
+ mode_count = 0;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
+ has_primary = 1;
+ primary_crtc = pScrPriv->primaryOutput->crtc;
+ crtcs[0] = pScrPriv->primaryOutput->crtc->id;
+ if (client->swapped)
+ swapl(&crtcs[0], n);
+ crtc_count = 1;
+ }
+ update_arrays(pScreen, pScrPriv, primary_crtc, has_primary);
+
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pScrPriv = rrGetScrPriv(iter);
+
+ update_arrays(iter, pScrPriv, primary_crtc, has_primary);
+ }
+
+ assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swapl(&rep.configTimestamp, n);
+ swaps(&rep.nCrtcs, n);
+ swaps(&rep.nOutputs, n);
+ swaps(&rep.nModes, n);
+ swaps(&rep.nbytesNames, n);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *) &rep);
+ if (extraLen) {
+ WriteToClient(client, extraLen, (char *) extra);
+ xfree(extra);
+ }
+ return Success;
+}
+#endif /* !defined(NXAGENT_SERVER) */
+
+static int
+rrGetScreenResources(ClientPtr client, Bool query)
{
REQUEST(xRRGetScreenResourcesReq);
xRRGetScreenResourcesReply rep;
@@ -336,15 +520,17 @@ ProcRRGetScreenResources(ClientPtr client)
rrScrPrivPtr pScrPriv;
CARD8 *extra;
unsigned long extraLen;
- int i, n, rc;
+ int i, rc, has_primary = 0;
RRCrtc *crtcs;
RROutput *outputs;
xRRModeInfo *modeinfos;
CARD8 *names;
+ int n;
REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
+
#ifndef NXAGENT_SERVER
- rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
@@ -354,22 +540,28 @@ ProcRRGetScreenResources(ClientPtr client)
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
- rep.pad = 0;
- if (pScrPriv)
- if (!RRGetInfo(pScreen))
+ if (query && pScrPriv)
+ if (!RRGetInfo(pScreen, query))
return BadAlloc;
+#ifndef NXAGENT_SERVER
+ if (!xorg_list_is_empty(&pScreen->output_slave_list))
+ return rrGetMultiScreenResources(client, query, pScreen);
+#endif
+
if (!pScrPriv) {
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.timestamp = currentTime.milliseconds;
- rep.configTimestamp = currentTime.milliseconds;
- rep.nCrtcs = 0;
- rep.nOutputs = 0;
- rep.nModes = 0;
- rep.nbytesNames = 0;
+ rep = (xRRGetScreenResourcesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = currentTime.milliseconds,
+ .configTimestamp = currentTime.milliseconds,
+ .nCrtcs = 0,
+ .nOutputs = 0,
+ .nModes = 0,
+ .nbytesNames = 0
+ };
extra = NULL;
extraLen = 0;
}
@@ -381,23 +573,25 @@ ProcRRGetScreenResources(ClientPtr client)
if (!modes)
return BadAlloc;
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.timestamp = pScrPriv->lastSetTime.milliseconds;
- rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
- rep.nCrtcs = pScrPriv->numCrtcs;
- rep.nOutputs = pScrPriv->numOutputs;
- rep.nModes = num_modes;
- rep.nbytesNames = 0;
+ rep = (xRRGetScreenResourcesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .nCrtcs = pScrPriv->numCrtcs,
+ .nOutputs = pScrPriv->numOutputs,
+ .nModes = num_modes,
+ .nbytesNames = 0
+ };
for (i = 0; i < num_modes; i++)
rep.nbytesNames += modes[i]->mode.nameLength;
rep.length = (pScrPriv->numCrtcs +
pScrPriv->numOutputs +
- num_modes * (SIZEOF(xRRModeInfo) >> 2) +
- ((rep.nbytesNames + 3) >> 2));
+ num_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) +
+ bytes_to_int32(rep.nbytesNames));
extraLen = rep.length << 2;
if (extraLen) {
@@ -415,10 +609,22 @@ ProcRRGetScreenResources(ClientPtr client)
modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs);
names = (CARD8 *) (modeinfos + num_modes);
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
+ has_primary = 1;
+ crtcs[0] = pScrPriv->primaryOutput->crtc->id;
+ if (client->swapped)
+ swapl(&crtcs[0], n);
+ }
+
for (i = 0; i < pScrPriv->numCrtcs; i++) {
- crtcs[i] = pScrPriv->crtcs[i]->id;
+ if (has_primary &&
+ pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) {
+ has_primary = 0;
+ continue;
+ }
+ crtcs[i + has_primary] = pScrPriv->crtcs[i]->id;
if (client->swapped)
- swapl(&crtcs[i], n);
+ swapl(&crtcs[i + has_primary], n);
}
for (i = 0; i < pScrPriv->numOutputs; i++) {
@@ -450,7 +656,7 @@ ProcRRGetScreenResources(ClientPtr client)
names += mode->mode.nameLength;
}
xfree(modes);
- assert(((((char *) names - (char *) extra) + 3) >> 2) == rep.length);
+ assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
}
if (client->swapped) {
@@ -463,12 +669,25 @@ ProcRRGetScreenResources(ClientPtr client)
swaps(&rep.nModes, n);
swaps(&rep.nbytesNames, n);
}
- WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *) &rep);
+ WriteToClient(client, sizeof(xRRGetScreenResourcesReply),
+ (char *) (char *) &rep);
if (extraLen) {
- WriteToClient(client, extraLen, (char *) extra);
+ WriteToClient(client, extraLen, (char *) (char *) extra);
xfree(extra);
}
- return client->noClientException;
+ return Success;
+}
+
+int
+ProcRRGetScreenResources(ClientPtr client)
+{
+ return rrGetScreenResources(client, TRUE);
+}
+
+int
+ProcRRGetScreenResourcesCurrent(ClientPtr client)
+{
+ return rrGetScreenResources(client, FALSE);
}
typedef struct _RR10Data {
@@ -495,7 +714,7 @@ RR10GetData(ScreenPtr pScreen, RROutputPtr output)
Bool *used;
/* Make sure there is plenty of space for any combination */
- data = malloc(sizeof(RR10DataRec) +
+ data = xalloc(sizeof(RR10DataRec) +
sizeof(RRScreenSize) * nmode +
sizeof(RRScreenRate) * nmode + sizeof(Bool) * nmode);
if (!data)
@@ -576,46 +795,49 @@ ProcRRGetScreenInfo(ClientPtr client)
REQUEST(xRRGetScreenInfoReq);
xRRGetScreenInfoReply rep;
WindowPtr pWin;
- int n, rc;
+ int rc;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
CARD8 *extra;
unsigned long extraLen;
RROutputPtr output;
+ int n;
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
#ifndef NXAGENT_SERVER
- rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
+
if (rc != Success)
return rc;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
- rep.pad = 0;
if (pScrPriv)
- if (!RRGetInfo(pScreen))
+ if (!RRGetInfo(pScreen, TRUE))
return BadAlloc;
output = RRFirstOutput(pScreen);
if (!pScrPriv || !output) {
- rep.type = X_Reply;
- rep.setOfRotations = RR_Rotate_0;;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
- rep.timestamp = currentTime.milliseconds;
- rep.configTimestamp = currentTime.milliseconds;
- rep.nSizes = 0;
- rep.sizeID = 0;
- rep.rotation = RR_Rotate_0;
- rep.rate = 0;
- rep.nrateEnts = 0;
+ rep = (xRRGetScreenInfoReply) {
+ .type = X_Reply,
+ .setOfRotations = RR_Rotate_0,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .root = pWin->drawable.pScreen->root->drawable.id,
+ .timestamp = currentTime.milliseconds,
+ .configTimestamp = currentTime.milliseconds,
+ .nSizes = 0,
+ .sizeID = 0,
+ .rotation = RR_Rotate_0,
+ .rate = 0,
+ .nrateEnts = 0
+ };
extra = 0;
extraLen = 0;
}
@@ -632,18 +854,20 @@ ProcRRGetScreenInfo(ClientPtr client)
if (!pData)
return BadAlloc;
- rep.type = X_Reply;
- rep.setOfRotations = output->crtc->rotations;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
- rep.timestamp = pScrPriv->lastSetTime.milliseconds;
- rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
- rep.rotation = output->crtc->rotation;
- rep.nSizes = pData->nsize;
- rep.nrateEnts = pData->nrefresh + pData->nsize;
- rep.sizeID = pData->size;
- rep.rate = pData->refresh;
+ rep = (xRRGetScreenInfoReply) {
+ .type = X_Reply,
+ .setOfRotations = output->crtc->rotations,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .root = pWin->drawable.pScreen->root->drawable.id,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .rotation = output->crtc->rotation,
+ .nSizes = pData->nsize,
+ .nrateEnts = pData->nrefresh + pData->nsize,
+ .sizeID = pData->size,
+ .rate = pData->refresh
+ };
extraLen = rep.nSizes * sizeof(xScreenSizes);
if (has_rate)
@@ -699,7 +923,7 @@ ProcRRGetScreenInfo(ClientPtr client)
if (data8 - (CARD8 *) extra != extraLen)
FatalError("RRGetScreenInfo bad extra len %ld != %ld\n",
(unsigned long) (data8 - (CARD8 *) extra), extraLen);
- rep.length = (extraLen + 3) >> 2;
+ rep.length = bytes_to_int32(extraLen);
}
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
@@ -717,7 +941,7 @@ ProcRRGetScreenInfo(ClientPtr client)
WriteToClient(client, extraLen, (char *) extra);
xfree(extra);
}
- return (client->noClientException);
+ return Success;
}
int
@@ -726,7 +950,7 @@ ProcRRSetScreenConfig(ClientPtr client)
REQUEST(xRRSetScreenConfigReq);
xRRSetScreenConfigReply rep;
DrawablePtr pDraw;
- int n, rc;
+ int rc;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
TimeStamp time;
@@ -734,12 +958,14 @@ ProcRRSetScreenConfig(ClientPtr client)
Rotation rotation;
int rate;
Bool has_rate;
+ CARD8 status;
RROutputPtr output;
RRCrtcPtr crtc;
RRModePtr mode;
RR10DataPtr pData = NULL;
RRScreenSizePtr pSize;
int width, height;
+ int n;
UpdateCurrentTime();
@@ -754,11 +980,12 @@ ProcRRSetScreenConfig(ClientPtr client)
#ifndef NXAGENT_SERVER
rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
-#else
+#else /* !defined(NXAGENT_SERVER) */
pDraw =
SecurityLookupDrawable(stuff->drawable, client, SecurityWriteAccess);
rc = pDraw ? Success : BadDrawable;
-#endif
+#endif /* !defined(NXAGENT_SERVER) */
+
if (rc != Success)
return rc;
@@ -770,16 +997,16 @@ ProcRRSetScreenConfig(ClientPtr client)
if (!pScrPriv) {
time = currentTime;
- rep.status = RRSetConfigFailed;
+ status = RRSetConfigFailed;
goto sendReply;
}
- if (!RRGetInfo(pScreen))
+ if (!RRGetInfo(pScreen, FALSE))
return BadAlloc;
output = RRFirstOutput(pScreen);
if (!output) {
time = currentTime;
- rep.status = RRSetConfigFailed;
+ status = RRSetConfigFailed;
goto sendReply;
}
@@ -795,7 +1022,7 @@ ProcRRSetScreenConfig(ClientPtr client)
* stop working after several hours have passed (freedesktop bug #6502).
*/
if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds) {
- rep.status = RRSetConfigInvalidConfigTime;
+ status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
@@ -874,7 +1101,7 @@ ProcRRSetScreenConfig(ClientPtr client)
* the last set-time
*/
if (CompareTimeStamps(time, pScrPriv->lastSetTime) < 0) {
- rep.status = RRSetConfigInvalidTime;
+ status = RRSetConfigInvalidTime;
goto sendReply;
}
@@ -884,11 +1111,6 @@ ProcRRSetScreenConfig(ClientPtr client)
*/
width = mode->mode.width;
height = mode->mode.height;
- if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- width = mode->mode.height;
- height = mode->mode.width;
- }
-
if (width < pScrPriv->minWidth || pScrPriv->maxWidth < width) {
client->errorValue = width;
xfree(pData);
@@ -900,30 +1122,35 @@ ProcRRSetScreenConfig(ClientPtr client)
return BadValue;
}
+ if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ width = mode->mode.height;
+ height = mode->mode.width;
+ }
+
if (width != pScreen->width || height != pScreen->height) {
int c;
for (c = 0; c < pScrPriv->numCrtcs; c++) {
if (!RRCrtcSet(pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0,
0, NULL)) {
- rep.status = RRSetConfigFailed;
+ status = RRSetConfigFailed;
/* XXX recover from failure */
goto sendReply;
}
}
if (!RRScreenSizeSet(pScreen, width, height,
pScreen->mmWidth, pScreen->mmHeight)) {
- rep.status = RRSetConfigFailed;
+ status = RRSetConfigFailed;
/* XXX recover from failure */
goto sendReply;
}
}
if (!RRCrtcSet(crtc, mode, 0, 0, stuff->rotation, 1, &output))
- rep.status = RRSetConfigFailed;
+ status = RRSetConfigFailed;
else {
pScrPriv->lastSetTime = time;
- rep.status = RRSetConfigSuccess;
+ status = RRSetConfigSuccess;
}
/*
@@ -932,17 +1159,18 @@ ProcRRSetScreenConfig(ClientPtr client)
sendReply:
- if (pData)
- xfree(pData);
-
- rep.type = X_Reply;
- /* rep.status has already been filled in */
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
+ xfree(pData);
- rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
- rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
- rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+ rep = (xRRSetScreenConfigReply) {
+ .type = X_Reply,
+ .status = status,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .newTimestamp = pScrPriv->lastSetTime.milliseconds,
+ .newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .root = pDraw->pScreen->root->drawable.id,
+ /* .subpixelOrder = ?? */
+ };
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
@@ -953,7 +1181,7 @@ ProcRRSetScreenConfig(ClientPtr client)
}
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *) &rep);
- return (client->noClientException);
+ return Success;
}
static CARD16
diff --git a/nx-X11/programs/Xserver/randr/rrsdispatch.c b/nx-X11/programs/Xserver/randr/rrsdispatch.c
index 3175340fa..6ac394344 100644
--- a/nx-X11/programs/Xserver/randr/rrsdispatch.c
+++ b/nx-X11/programs/Xserver/randr/rrsdispatch.c
@@ -25,7 +25,7 @@
static int
SProcRRQueryVersion(ClientPtr client)
{
- register int n;
+ int n;
REQUEST(xRRQueryVersionReq);
@@ -39,7 +39,7 @@ SProcRRQueryVersion(ClientPtr client)
static int
SProcRRGetScreenInfo(ClientPtr client)
{
- register int n;
+ int n;
REQUEST(xRRGetScreenInfoReq);
@@ -52,7 +52,7 @@ SProcRRGetScreenInfo(ClientPtr client)
static int
SProcRRSetScreenConfig(ClientPtr client)
{
- register int n;
+ int n;
REQUEST(xRRSetScreenConfigReq);
@@ -75,7 +75,7 @@ SProcRRSetScreenConfig(ClientPtr client)
static int
SProcRRSelectInput(ClientPtr client)
{
- register int n;
+ int n;
REQUEST(xRRSelectInputReq);
@@ -134,7 +134,7 @@ SProcRRGetOutputInfo(ClientPtr client)
{
int n;
- REQUEST(xRRGetOutputInfoReq);;
+ REQUEST(xRRGetOutputInfoReq);
REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
swaps(&stuff->length, n);
@@ -177,6 +177,7 @@ SProcRRConfigureOutputProperty(ClientPtr client)
REQUEST(xRRConfigureOutputPropertyReq);
+ REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
swaps(&stuff->length, n);
swapl(&stuff->output, n);
swapl(&stuff->property, n);
@@ -248,6 +249,7 @@ static int
SProcRRCreateMode(ClientPtr client)
{
int n;
+
xRRModeInfo *modeinfo;
REQUEST(xRRCreateModeReq);
@@ -388,6 +390,315 @@ SProcRRSetCrtcGamma(ClientPtr client)
return (*ProcRandrVector[stuff->randrReqType]) (client);
}
+static int
+SProcRRSetCrtcTransform(ClientPtr client)
+{
+ int nparams;
+ char *filter;
+ CARD32 *params;
+ int n;
+
+ REQUEST(xRRSetCrtcTransformReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ SwapLongs((CARD32 *) &stuff->transform,
+ bytes_to_int32(sizeof(xRenderTransform)));
+ swaps(&stuff->nbytesFilter, n);
+ filter = (char *) (stuff + 1);
+ params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter));
+ nparams = ((CARD32 *) stuff + client->req_len) - params;
+ if (nparams < 0)
+ return BadLength;
+
+ SwapLongs(params, nparams);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcTransform(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRGetCrtcTransformReq);
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetPanning(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRGetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetPanning(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRSetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ swapl(&stuff->timestamp, n);
+ swaps(&stuff->left, n);
+ swaps(&stuff->top, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swaps(&stuff->track_left, n);
+ swaps(&stuff->track_top, n);
+ swaps(&stuff->track_width, n);
+ swaps(&stuff->track_height, n);
+ swaps(&stuff->border_left, n);
+ swaps(&stuff->border_top, n);
+ swaps(&stuff->border_right, n);
+ swaps(&stuff->border_bottom, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetOutputPrimary(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRSetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->output, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetOutputPrimary(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRGetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetProviders(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRGetProvidersReq);
+
+ REQUEST_SIZE_MATCH(xRRGetProvidersReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetProviderInfo(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRGetProviderInfoReq);
+
+ REQUEST_SIZE_MATCH(xRRGetProviderInfoReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->configTimestamp, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRSetProviderOffloadSink(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRSetProviderOffloadSinkReq);
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->sink_provider, n);
+ swapl(&stuff->configTimestamp, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRSetProviderOutputSource(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRSetProviderOutputSourceReq);
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->source_provider, n);
+ swapl(&stuff->configTimestamp, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRListProviderProperties(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRListProviderPropertiesReq);
+
+ REQUEST_SIZE_MATCH(xRRListProviderPropertiesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRQueryProviderProperty(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRQueryProviderPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRQueryProviderPropertyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->property, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRConfigureProviderProperty(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRConfigureProviderPropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRConfigureProviderPropertyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->property, n);
+ /* TODO: no way to specify format? */
+ SwapRestL(stuff);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRChangeProviderProperty(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRChangeProviderPropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ switch (stuff->format) {
+ case 8:
+ break;
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRDeleteProviderProperty(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRDeleteProviderPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRDeleteProviderPropertyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->property, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetProviderProperty(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRGetProviderPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRGetProviderPropertyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->provider, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetMonitors(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRGetMonitorsReq);
+
+ REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRSetMonitor(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRSetMonitorReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRGetMonitorsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->monitor.name, n);
+ swaps(&stuff->monitor.noutput, n);
+ swaps(&stuff->monitor.x, n);
+ swaps(&stuff->monitor.y, n);
+ swaps(&stuff->monitor.width, n);
+ swaps(&stuff->monitor.height, n);
+ SwapRestL(stuff);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRDeleteMonitor(ClientPtr client)
+{
+ int n;
+
+ REQUEST(xRRDeleteMonitorReq);
+
+ REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->name, n);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = {
SProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
@@ -418,4 +729,26 @@ int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = {
SProcRRGetCrtcGammaSize, /* 22 */
SProcRRGetCrtcGamma, /* 23 */
SProcRRSetCrtcGamma, /* 24 */
+/* V1.3 additions */
+ SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */
+ SProcRRSetCrtcTransform, /* 26 */
+ SProcRRGetCrtcTransform, /* 27 */
+ SProcRRGetPanning, /* 28 */
+ SProcRRSetPanning, /* 29 */
+ SProcRRSetOutputPrimary, /* 30 */
+ SProcRRGetOutputPrimary, /* 31 */
+/* V1.4 additions */
+ SProcRRGetProviders, /* 32 */
+ SProcRRGetProviderInfo, /* 33 */
+ SProcRRSetProviderOffloadSink, /* 34 */
+ SProcRRSetProviderOutputSource, /* 35 */
+ SProcRRListProviderProperties, /* 36 */
+ SProcRRQueryProviderProperty, /* 37 */
+ SProcRRConfigureProviderProperty, /* 38 */
+ SProcRRChangeProviderProperty, /* 39 */
+ SProcRRDeleteProviderProperty, /* 40 */
+ SProcRRGetProviderProperty, /* 41 */
+ SProcRRGetMonitors, /* 42 */
+ SProcRRSetMonitor, /* 43 */
+ SProcRRDeleteMonitor, /* 44 */
};
diff --git a/nx-X11/programs/Xserver/randr/rrtransform.c b/nx-X11/programs/Xserver/randr/rrtransform.c
new file mode 100644
index 000000000..4377d09aa
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrtransform.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright © 2007 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"
+#include "rrtransform.h"
+
+void
+RRTransformInit(RRTransformPtr transform)
+{
+ pixman_transform_init_identity(&transform->transform);
+ pixman_f_transform_init_identity(&transform->f_transform);
+ pixman_f_transform_init_identity(&transform->f_inverse);
+ transform->filter = NULL;
+ transform->params = NULL;
+ transform->nparams = 0;
+}
+
+void
+RRTransformFini(RRTransformPtr transform)
+{
+ xfree(transform->params);
+}
+
+Bool
+RRTransformEqual(RRTransformPtr a, RRTransformPtr b)
+{
+ if (a && pixman_transform_is_identity(&a->transform))
+ a = NULL;
+ if (b && pixman_transform_is_identity(&b->transform))
+ b = NULL;
+ if (a == NULL && b == NULL)
+ return TRUE;
+ if (a == NULL || b == NULL)
+ return FALSE;
+ if (memcmp(&a->transform, &b->transform, sizeof(a->transform)) != 0)
+ return FALSE;
+ if (a->filter != b->filter)
+ return FALSE;
+ if (a->nparams != b->nparams)
+ return FALSE;
+ if (memcmp(a->params, b->params, a->nparams * sizeof(xFixed)) != 0)
+ return FALSE;
+ return TRUE;
+}
+
+Bool
+RRTransformSetFilter(RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed * params, int nparams, int width, int height)
+{
+ xFixed *new_params;
+
+ if (nparams) {
+#ifndef NXAGENT_SERVER
+ new_params = xallocarray(nparams, sizeof(xFixed));
+#else /* !defined(NXAGENT_SERVER) */
+ new_params = xalloc(nparams * sizeof(xFixed));
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!new_params)
+ return FALSE;
+ memcpy(new_params, params, nparams * sizeof(xFixed));
+ }
+ else
+ new_params = NULL;
+ xfree(dst->params);
+ dst->filter = filter;
+ dst->params = new_params;
+ dst->nparams = nparams;
+ dst->width = width;
+ dst->height = height;
+ return TRUE;
+}
+
+Bool
+RRTransformCopy(RRTransformPtr dst, RRTransformPtr src)
+{
+ if (src && pixman_transform_is_identity(&src->transform))
+ src = NULL;
+
+ if (src) {
+ if (!RRTransformSetFilter(dst, src->filter,
+ src->params, src->nparams, src->width,
+ src->height))
+ return FALSE;
+ dst->transform = src->transform;
+ dst->f_transform = src->f_transform;
+ dst->f_inverse = src->f_inverse;
+ }
+ else {
+ if (!RRTransformSetFilter(dst, NULL, NULL, 0, 0, 0))
+ return FALSE;
+ pixman_transform_init_identity(&dst->transform);
+ pixman_f_transform_init_identity(&dst->f_transform);
+ pixman_f_transform_init_identity(&dst->f_inverse);
+ }
+ return TRUE;
+}
+
+#define F(x) IntToxFixed(x)
+
+static void
+RRTransformRescale(struct pixman_f_transform *f_transform, double limit)
+{
+ double max = 0, v, scale;
+ int i, j;
+
+ for (j = 0; j < 3; j++)
+ for (i = 0; i < 3; i++)
+ if ((v = fabs(f_transform->m[j][i])) > max)
+ max = v;
+ scale = limit / max;
+ for (j = 0; j < 3; j++)
+ for (i = 0; i < 3; i++)
+ f_transform->m[j][i] *= scale;
+}
+
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+Bool
+RRTransformCompute(int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+ PictTransformPtr transform,
+ struct pixman_f_transform *f_transform,
+ struct pixman_f_transform *f_inverse)
+{
+ PictTransform t_transform, inverse;
+ struct pixman_f_transform tf_transform, tf_inverse;
+ Bool overflow = FALSE;
+
+ if (!transform)
+ transform = &t_transform;
+ if (!f_transform)
+ f_transform = &tf_transform;
+ if (!f_inverse)
+ f_inverse = &tf_inverse;
+
+ pixman_transform_init_identity(transform);
+ pixman_transform_init_identity(&inverse);
+ pixman_f_transform_init_identity(f_transform);
+ pixman_f_transform_init_identity(f_inverse);
+ if (rotation != RR_Rotate_0) {
+ double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
+ double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
+ xFixed rot_cos, rot_sin, rot_dx, rot_dy;
+ xFixed scale_x, scale_y, scale_dx, scale_dy;
+
+ /* rotation */
+ switch (rotation & 0xf) {
+ default:
+ case RR_Rotate_0:
+ f_rot_cos = 1;
+ f_rot_sin = 0;
+ f_rot_dx = 0;
+ f_rot_dy = 0;
+ rot_cos = F(1);
+ rot_sin = F(0);
+ rot_dx = F(0);
+ rot_dy = F(0);
+ break;
+ case RR_Rotate_90:
+ f_rot_cos = 0;
+ f_rot_sin = 1;
+ f_rot_dx = height;
+ f_rot_dy = 0;
+ rot_cos = F(0);
+ rot_sin = F(1);
+ rot_dx = F(height);
+ rot_dy = F(0);
+ break;
+ case RR_Rotate_180:
+ f_rot_cos = -1;
+ f_rot_sin = 0;
+ f_rot_dx = width;
+ f_rot_dy = height;
+ rot_cos = F(~0u);
+ rot_sin = F(0);
+ rot_dx = F(width);
+ rot_dy = F(height);
+ break;
+ case RR_Rotate_270:
+ f_rot_cos = 0;
+ f_rot_sin = -1;
+ f_rot_dx = 0;
+ f_rot_dy = width;
+ rot_cos = F(0);
+ rot_sin = F(~0u);
+ rot_dx = F(0);
+ rot_dy = F(width);
+ break;
+ }
+
+ pixman_transform_rotate(transform, &inverse, rot_cos, rot_sin);
+ pixman_transform_translate(transform, &inverse, rot_dx, rot_dy);
+ pixman_f_transform_rotate(f_transform, f_inverse, f_rot_cos, f_rot_sin);
+ pixman_f_transform_translate(f_transform, f_inverse, f_rot_dx,
+ f_rot_dy);
+
+ /* reflection */
+ f_scale_x = 1;
+ f_scale_dx = 0;
+ f_scale_y = 1;
+ f_scale_dy = 0;
+ scale_x = F(1);
+ scale_dx = 0;
+ scale_y = F(1);
+ scale_dy = 0;
+ if (rotation & RR_Reflect_X) {
+ f_scale_x = -1;
+ scale_x = F(~0u);
+ if (rotation & (RR_Rotate_0 | RR_Rotate_180)) {
+ f_scale_dx = width;
+ scale_dx = F(width);
+ }
+ else {
+ f_scale_dx = height;
+ scale_dx = F(height);
+ }
+ }
+ if (rotation & RR_Reflect_Y) {
+ f_scale_y = -1;
+ scale_y = F(~0u);
+ if (rotation & (RR_Rotate_0 | RR_Rotate_180)) {
+ f_scale_dy = height;
+ scale_dy = F(height);
+ }
+ else {
+ f_scale_dy = width;
+ scale_dy = F(width);
+ }
+ }
+
+ pixman_transform_scale(transform, &inverse, scale_x, scale_y);
+ pixman_f_transform_scale(f_transform, f_inverse, f_scale_x, f_scale_y);
+ pixman_transform_translate(transform, &inverse, scale_dx, scale_dy);
+ pixman_f_transform_translate(f_transform, f_inverse, f_scale_dx,
+ f_scale_dy);
+ }
+
+#ifdef RANDR_12_INTERFACE
+ if (rr_transform) {
+ if (!pixman_transform_multiply
+ (transform, &rr_transform->transform, transform))
+ overflow = TRUE;
+ pixman_f_transform_multiply(f_transform, &rr_transform->f_transform,
+ f_transform);
+ pixman_f_transform_multiply(f_inverse, f_inverse,
+ &rr_transform->f_inverse);
+ }
+#endif
+ /*
+ * Compute the class of the resulting transform
+ */
+ if (!overflow && pixman_transform_is_identity(transform)) {
+ pixman_transform_init_translate(transform, F(x), F(y));
+
+ pixman_f_transform_init_translate(f_transform, x, y);
+ pixman_f_transform_init_translate(f_inverse, -x, -y);
+ return FALSE;
+ }
+ else {
+ pixman_f_transform_translate(f_transform, f_inverse, x, y);
+ if (!pixman_transform_translate(transform, &inverse, F(x), F(y)))
+ overflow = TRUE;
+ if (overflow) {
+ struct pixman_f_transform f_scaled;
+
+ f_scaled = *f_transform;
+ RRTransformRescale(&f_scaled, 16384.0);
+ pixman_transform_from_pixman_f_transform(transform, &f_scaled);
+ }
+ return TRUE;
+ }
+}
diff --git a/nx-X11/programs/Xserver/randr/rrtransform.h b/nx-X11/programs/Xserver/randr/rrtransform.h
new file mode 100644
index 000000000..2433a0f73
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrtransform.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2007 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.
+ */
+
+#ifndef _RRTRANSFORM_H_
+#define _RRTRANSFORM_H_
+
+#include "randr.h"
+#include "picturestr.h"
+
+typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
+
+struct _rrTransform {
+ PictTransform transform;
+ struct pict_f_transform f_transform;
+ struct pict_f_transform f_inverse;
+ PictFilterPtr filter;
+ xFixed *params;
+ int nparams;
+ int width;
+ int height;
+};
+
+extern _X_EXPORT void
+ RRTransformInit(RRTransformPtr transform);
+
+extern _X_EXPORT void
+ RRTransformFini(RRTransformPtr transform);
+
+extern _X_EXPORT Bool
+ RRTransformEqual(RRTransformPtr a, RRTransformPtr b);
+
+extern _X_EXPORT Bool
+
+RRTransformSetFilter(RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed * params, int nparams, int width, int height);
+
+extern _X_EXPORT Bool
+ RRTransformCopy(RRTransformPtr dst, RRTransformPtr src);
+
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+extern _X_EXPORT Bool
+
+RRTransformCompute(int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse);
+
+#endif /* _RRTRANSFORM_H_ */
diff --git a/nx-X11/programs/Xserver/randr/rrxinerama.c b/nx-X11/programs/Xserver/randr/rrxinerama.c
index 31b750d64..9a164578f 100644
--- a/nx-X11/programs/Xserver/randr/rrxinerama.c
+++ b/nx-X11/programs/Xserver/randr/rrxinerama.c
@@ -87,15 +87,14 @@
#include "randrstr.h"
#include "swaprep.h"
+#include "panoramiXproto.h"
#ifndef NXAGENT_SERVER
-#include <nx-X11/extensions/panoramiXproto.h>
+#include "protocol-versions.h"
#else
-#include "panoramiXproto.h"
+#define SERVER_RRXINERAMA_MAJOR_VERSION 1
+#define SERVER_RRXINERAMA_MINOR_VERSION 1
#endif
-#define RR_XINERAMA_MAJOR_VERSION 1
-#define RR_XINERAMA_MINOR_VERSION 1
-
/* Xinerama is not multi-screen capable; just report about screen 0 */
#define RR_XINERAMA_SCREEN 0
@@ -114,15 +113,17 @@ extern Bool noRRXineramaExtension;
int
ProcRRXineramaQueryVersion(ClientPtr client)
{
- xPanoramiXQueryVersionReply rep;
- register int n;
+ int n;
+
+ xPanoramiXQueryVersionReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .majorVersion = SERVER_RRXINERAMA_MAJOR_VERSION,
+ .minorVersion = SERVER_RRXINERAMA_MINOR_VERSION
+ };
REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = RR_XINERAMA_MAJOR_VERSION;
- rep.minorVersion = RR_XINERAMA_MINOR_VERSION;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
@@ -130,7 +131,7 @@ ProcRRXineramaQueryVersion(ClientPtr client)
swaps(&rep.minorVersion, n);
}
WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *) &rep);
- return (client->noClientException);
+ return Success;
}
int
@@ -139,10 +140,11 @@ ProcRRXineramaGetState(ClientPtr client)
REQUEST(xPanoramiXGetStateReq);
WindowPtr pWin;
xPanoramiXGetStateReply rep;
- register int n, rc;
+ register int rc;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
Bool active = FALSE;
+ int n;
REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
#ifndef NXAGENT_SERVER
@@ -151,6 +153,7 @@ ProcRRXineramaGetState(ClientPtr client)
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
+
if (rc != Success)
return rc;
@@ -161,39 +164,26 @@ ProcRRXineramaGetState(ClientPtr client)
active = TRUE;
}
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = active;
- rep.window = stuff->window;
+ rep = (xPanoramiXGetStateReply) {
+ .type = X_Reply,
+ .state = active,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .window = stuff->window
+ };
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.window, n);
}
WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *) &rep);
- return client->noClientException;
-}
-
-static Bool
-RRXineramaCrtcActive(RRCrtcPtr crtc)
-{
- return crtc->mode != NULL && crtc->numOutputs > 0;
+ return Success;
}
static int
RRXineramaScreenCount(ScreenPtr pScreen)
{
- int i, n;
-
- n = 0;
- if (rrGetScrPriv(pScreen)) {
- rrScrPriv(pScreen);
- for (i = 0; i < pScrPriv->numCrtcs; i++)
- if (RRXineramaCrtcActive(pScrPriv->crtcs[i]))
- n++;
- }
- return n;
+ return RRMonitorCountList(pScreen);
}
static Bool
@@ -208,9 +198,11 @@ ProcRRXineramaGetScreenCount(ClientPtr client)
REQUEST(xPanoramiXGetScreenCountReq);
WindowPtr pWin;
xPanoramiXGetScreenCountReply rep;
- register int n, rc;
+ register int rc;
+ int n;
REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
@@ -220,18 +212,20 @@ ProcRRXineramaGetScreenCount(ClientPtr client)
if (rc != Success)
return rc;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.ScreenCount = RRXineramaScreenCount(pWin->drawable.pScreen);
- rep.window = stuff->window;
+ rep = (xPanoramiXGetScreenCountReply) {
+ .type = X_Reply,
+ .ScreenCount = RRXineramaScreenCount(pWin->drawable.pScreen),
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .window = stuff->window
+ };
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.window, n);
}
WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *) &rep);
- return client->noClientException;
+ return Success;
}
int
@@ -241,7 +235,8 @@ ProcRRXineramaGetScreenSize(ClientPtr client)
WindowPtr pWin, pRoot;
ScreenPtr pScreen;
xPanoramiXGetScreenSizeReply rep;
- register int n, rc;
+ register int rc;
+ int n;
REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
#ifndef NXAGENT_SERVER
@@ -250,19 +245,22 @@ ProcRRXineramaGetScreenSize(ClientPtr client)
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
+
if (rc != Success)
return rc;
pScreen = pWin->drawable.pScreen;
- pRoot = WindowTable[pScreen->myNum];
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.width = pRoot->drawable.width;
- rep.height = pRoot->drawable.height;
- rep.window = stuff->window;
- rep.screen = stuff->screen;
+ pRoot = pScreen->root;
+
+ rep = (xPanoramiXGetScreenSizeReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .width = pRoot->drawable.width,
+ .height = pRoot->drawable.height,
+ .window = stuff->window,
+ .screen = stuff->screen
+ };
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
@@ -272,30 +270,43 @@ ProcRRXineramaGetScreenSize(ClientPtr client)
swapl(&rep.screen, n);
}
WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *) &rep);
- return client->noClientException;
+ return Success;
}
int
ProcRRXineramaIsActive(ClientPtr client)
{
xXineramaIsActiveReply rep;
+ int n;
REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
- memset(&rep, 0, sizeof(xXineramaIsActiveReply));
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN]);
+ rep = (xXineramaIsActiveReply) {
+ .type = X_Reply,
+ .length = 0,
+ .sequenceNumber = client->sequence,
+ .state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN])
+ };
if (client->swapped) {
- register int n;
-
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.state, n);
}
WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
- return client->noClientException;
+ return Success;
+}
+
+static void
+RRXineramaWriteMonitor(ClientPtr client, RRMonitorPtr monitor)
+{
+ xXineramaScreenInfo scratch;
+
+ scratch.x_org = monitor->geometry.box.x1;
+ scratch.y_org = monitor->geometry.box.y1;
+ scratch.width = monitor->geometry.box.x2 - monitor->geometry.box.x1;
+ scratch.height = monitor->geometry.box.y2 - monitor->geometry.box.y1;
+
+ WriteToClient(client, sz_XineramaScreenInfo, (char *) &scratch);
}
int
@@ -303,58 +314,39 @@ ProcRRXineramaQueryScreens(ClientPtr client)
{
xXineramaQueryScreensReply rep;
ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
+ int m;
+ RRMonitorPtr monitors = NULL;
+ int nmonitors = 0;
+ int n;
REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
if (RRXineramaScreenActive(pScreen)) {
- rrScrPriv(pScreen);
- if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0)
- RRGetInfo(pScreen);
+ RRGetInfo(pScreen, FALSE);
+ if (!RRMonitorMakeList(pScreen, TRUE, &monitors, &nmonitors))
+ return BadAlloc;
}
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.number = RRXineramaScreenCount(pScreen);
- rep.length = rep.number * sz_XineramaScreenInfo >> 2;
+ rep = (xXineramaQueryScreensReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(nmonitors * sz_XineramaScreenInfo),
+ .number = nmonitors
+ };
if (client->swapped) {
- register int n;
-
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.number, n);
}
WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *) &rep);
- if (rep.number) {
- rrScrPriv(pScreen);
- xXineramaScreenInfo scratch;
- int i;
-
- for (i = 0; i < pScrPriv->numCrtcs; i++) {
- RRCrtcPtr crtc = pScrPriv->crtcs[i];
-
- if (RRXineramaCrtcActive(crtc)) {
- int width, height;
-
- RRCrtcGetScanoutSize(crtc, &width, &height);
- scratch.x_org = crtc->x;
- scratch.y_org = crtc->y;
- scratch.width = width;
- scratch.height = height;
- if (client->swapped) {
- register int n;
-
- swaps(&scratch.x_org, n);
- swaps(&scratch.y_org, n);
- swaps(&scratch.width, n);
- swaps(&scratch.height, n);
- }
- WriteToClient(client, sz_XineramaScreenInfo, (char *) &scratch);
- }
- }
- }
+ for (m = 0; m < nmonitors; m++)
+ RRXineramaWriteMonitor(client, &monitors[m]);
+
+ if (monitors)
+ RRMonitorFreeList(monitors, nmonitors);
- return client->noClientException;
+ return Success;
}
static int
@@ -383,9 +375,9 @@ ProcRRXineramaDispatch(ClientPtr client)
static int
SProcRRXineramaQueryVersion(ClientPtr client)
{
- REQUEST(xPanoramiXQueryVersionReq);
- register int n;
+ int n;
+ REQUEST(xPanoramiXQueryVersionReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
return ProcRRXineramaQueryVersion(client);
@@ -394,9 +386,9 @@ SProcRRXineramaQueryVersion(ClientPtr client)
static int
SProcRRXineramaGetState(ClientPtr client)
{
- REQUEST(xPanoramiXGetStateReq);
- register int n;
+ int n;
+ REQUEST(xPanoramiXGetStateReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
swapl(&stuff->window, n);
@@ -406,9 +398,9 @@ SProcRRXineramaGetState(ClientPtr client)
static int
SProcRRXineramaGetScreenCount(ClientPtr client)
{
- REQUEST(xPanoramiXGetScreenCountReq);
- register int n;
+ int n;
+ REQUEST(xPanoramiXGetScreenCountReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
swapl(&stuff->window, n);
@@ -418,9 +410,9 @@ SProcRRXineramaGetScreenCount(ClientPtr client)
static int
SProcRRXineramaGetScreenSize(ClientPtr client)
{
- REQUEST(xPanoramiXGetScreenSizeReq);
- register int n;
+ int n;
+ REQUEST(xPanoramiXGetScreenSizeReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
swapl(&stuff->window, n);
@@ -431,9 +423,9 @@ SProcRRXineramaGetScreenSize(ClientPtr client)
static int
SProcRRXineramaIsActive(ClientPtr client)
{
- REQUEST(xXineramaIsActiveReq);
- register int n;
+ int n;
+ REQUEST(xXineramaIsActiveReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
return ProcRRXineramaIsActive(client);
@@ -442,9 +434,9 @@ SProcRRXineramaIsActive(ClientPtr client)
static int
SProcRRXineramaQueryScreens(ClientPtr client)
{
- REQUEST(xXineramaQueryScreensReq);
- register int n;
+ int n;
+ REQUEST(xXineramaQueryScreensReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
return ProcRRXineramaQueryScreens(client);
@@ -471,11 +463,6 @@ SProcRRXineramaDispatch(ClientPtr client)
return BadRequest;
}
-static void
-RRXineramaResetProc(ExtensionEntry * extEntry)
-{
-}
-
void
RRXineramaExtensionInit(void)
{
@@ -484,6 +471,9 @@ RRXineramaExtensionInit(void)
return;
#endif
+ if (noRRXineramaExtension)
+ return;
+
/*
* Xinerama isn't capable enough to have multiple protocol screens each
* with their own output geometry. So if there's more than one protocol
@@ -494,6 +484,5 @@ RRXineramaExtensionInit(void)
(void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
ProcRRXineramaDispatch,
- SProcRRXineramaDispatch,
- RRXineramaResetProc, StandardMinorOpcode);
+ SProcRRXineramaDispatch, NULL, StandardMinorOpcode);
}