Unverified Commit 17f3e3bc authored by Mike Gabriel's avatar Mike Gabriel

Merge branch 'sunweaver-pr/xrandr-extension-upgrade-1.5' into 3.6.x

Attributes GH PR #137: https://github.com/ArcticaProject/nx-libs/pull/137 Reviewed by: Ulrich Sibiller <uli42@gmx.de> -- Mon, 20 Jun 2016 12:40:52 -0700
parents 9013a24d 4c8fc6be
......@@ -28,7 +28,7 @@ Build-Depends:
pkg-config,
x11proto-core-dev,
expat,
libpixman-1-dev,
libpixman-1-dev (>= 0.13.2),
Standards-Version: 3.9.6
Homepage: http://code.x2go.org/gitweb?p=nx-libs.git;a=summary
Vcs-Git: git://code.x2go.org/nx-libs.git
......
......@@ -323,7 +323,7 @@ index 862f75a..5405568 100644
x.u.u.type = SelectionRequest;
x.u.selectionRequest.time = GetTimeInMillis();
x.u.selectionRequest.owner = lastOwnerWindow;
x.u.selectionRequest.requestor = WindowTable[0]->drawable.id;
x.u.selectionRequest.requestor = screenInfo.screens[0]->root->drawable.id;
- x.u.selectionRequest.selection = XA_PRIMARY;
+/* My changes */
+/*
......
......@@ -8,7 +8,7 @@ Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Last-Update: 2012-01-12
--- a/nx-X11/programs/Xserver/Xext/security.c
+++ b/nx-X11/programs/Xserver/Xext/security.c
@@ -86,7 +86,7 @@
@@ -78,7 +78,7 @@
#ifdef NXAGENT_SERVER
......
......@@ -896,7 +896,7 @@ void PanoramiXConsolidate(void)
for (i = 0; i < PanoramiXNumScreens; i++) {
root->info[i].id = WindowTable[i]->drawable.id;
root->info[i].id = screenInfo.screens[i]->root->drawable.id;
root->u.win.class = InputOutput;
root->u.win.root = TRUE;
saver->info[i].id = savedScreenInfo[i].wid;
......
......@@ -89,11 +89,11 @@ typedef struct {
#define FORCE_ROOT(a) { \
int _j; \
for (_j = PanoramiXNumScreens - 1; _j; _j--) \
if ((a).root == WindowTable[_j]->drawable.id) \
if ((a).root == screenInfo.screens[_j]->root->drawable.id) \
break; \
(a).rootX += panoramiXdataPtr[_j].x; \
(a).rootY += panoramiXdataPtr[_j].y; \
(a).root = WindowTable[0]->drawable.id; \
(a).root = screenInfo.screens[0]->root->drawable.id; \
}
#define FORCE_WIN(a) { \
......
......@@ -146,7 +146,7 @@ int PanoramiXCreateWindow(ClientPtr client)
orig_visual = stuff->visual;
orig_x = stuff->x;
orig_y = stuff->y;
parentIsRoot = (stuff->parent == WindowTable[0]->drawable.id) ||
parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
(stuff->parent == savedScreenInfo[0].wid);
FOR_NSCREENS_BACKWARD(j) {
stuff->wid = newWin->info[j].id;
......@@ -336,7 +336,7 @@ int PanoramiXReparentWindow(ClientPtr client)
x = stuff->x;
y = stuff->y;
parentIsRoot = (stuff->parent == WindowTable[0]->drawable.id) ||
parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
(stuff->parent == savedScreenInfo[0].wid);
FOR_NSCREENS_BACKWARD(j) {
stuff->window = win->info[j].id;
......@@ -476,7 +476,7 @@ int PanoramiXConfigureWindow(ClientPtr client)
}
}
if(pWin->parent && ((pWin->parent == WindowTable[0]) ||
if(pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) ||
(pWin->parent->drawable.id == savedScreenInfo[0].wid)))
{
if ((Mask)stuff->mask & CWX) {
......@@ -540,7 +540,7 @@ int PanoramiXGetGeometry(ClientPtr client)
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.root = WindowTable[0]->drawable.id;
rep.root = screenInfo.screens[0]->root->drawable.id;
rep.depth = pDraw->depth;
rep.width = pDraw->width;
rep.height = pDraw->height;
......@@ -558,7 +558,7 @@ int PanoramiXGetGeometry(ClientPtr client)
WindowPtr pWin = (WindowPtr)pDraw;
rep.x = pWin->origin.x - wBorderWidth (pWin);
rep.y = pWin->origin.y - wBorderWidth (pWin);
if((pWin->parent == WindowTable[0]) ||
if((pWin->parent == screenInfo.screens[0]->root) ||
(pWin->parent->drawable.id == savedScreenInfo[0].wid))
{
rep.x += panoramiXdataPtr[0].x;
......@@ -594,7 +594,7 @@ int PanoramiXTranslateCoords(ClientPtr client)
rep.sameScreen = xTrue;
rep.child = None;
if((pWin == WindowTable[0]) ||
if((pWin == screenInfo.screens[0]->root) ||
(pWin->drawable.id == savedScreenInfo[0].wid))
{
x = stuff->srcX - panoramiXdataPtr[0].x;
......@@ -636,7 +636,7 @@ int PanoramiXTranslateCoords(ClientPtr client)
}
rep.dstX = x - pDst->drawable.x;
rep.dstY = y - pDst->drawable.y;
if((pDst == WindowTable[0]) ||
if((pDst == screenInfo.screens[0]->root) ||
(pDst->drawable.id == savedScreenInfo[0].wid))
{
rep.dstX += panoramiXdataPtr[0].x;
......
......@@ -473,7 +473,7 @@ SendScreenSaverNotify (pScreen, state, forced)
ev.state = state;
ev.sequenceNumber = client->sequence;
ev.timestamp = currentTime.milliseconds;
ev.root = WindowTable[pScreen->myNum]->drawable.id;
ev.root = pScreen->root->drawable.id;
ev.window = savedScreenInfo[pScreen->myNum].wid;
ev.kind = kind;
ev.forced = forced;
......@@ -549,7 +549,7 @@ CreateSaverWindow (pScreen)
if (GrabInProgress && GrabInProgress != pAttr->client->index)
return FALSE;
pWin = CreateWindow (pSaver->wid, WindowTable[pScreen->myNum],
pWin = CreateWindow (pSaver->wid, pScreen->root,
pAttr->x, pAttr->y, pAttr->width, pAttr->height,
pAttr->borderWidth, pAttr->class,
pAttr->mask, (XID *)pAttr->values,
......@@ -830,7 +830,7 @@ ScreenSaverSetAttributes (ClientPtr client)
if (!pDraw)
return BadDrawable;
pScreen = pDraw->pScreen;
pParent = WindowTable[pScreen->myNum];
pParent = pScreen->root;
len = stuff->length - (sizeof(xScreenSaverSetAttributesReq) >> 2);
if (Ones(stuff->mask) != len)
......
......@@ -409,7 +409,7 @@ ProcXTestFakeInput(client)
if (RegionContainsPoint(
&XineramaScreenRegions[i],
x, y, &box)) {
root = WindowTable[i];
root = screenInfo.screens[i]->root;
x -= panoramiXdataPtr[i].x;
y -= panoramiXdataPtr[i].y;
ev->u.keyButtonPointer.rootX = x;
......
......@@ -208,7 +208,7 @@ SendEventToAllWindows (dev, mask, ev, count)
for (i=0; i<screenInfo.numScreens; i++)
{
pWin = WindowTable[i];
pWin = screenInfo.screens[i]->root;
(void)DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, dev->id);
p1 = pWin->firstChild;
FindInterestedChildren (dev, p1, mask, ev, count);
......
......@@ -124,7 +124,7 @@ ProcXCloseDevice(client)
for (i=0; i<screenInfo.numScreens; i++)
{
pWin = WindowTable[i];
pWin = screenInfo.screens[i]->root;
DeleteDeviceEvents (d, pWin, client);
p1 = pWin->firstChild;
DeleteEventsFromChildren (d, p1, client);
......
......@@ -32,7 +32,7 @@ static void
compScreenUpdate(ScreenPtr pScreen)
{
compCheckTree(pScreen);
compPaintChildrenToWindow(pScreen, WindowTable[pScreen->myNum]);
compPaintChildrenToWindow(pScreen, pScreen->root);
}
static void
......
......@@ -129,7 +129,7 @@ Bool
compCreateOverlayWindow(ScreenPtr pScreen)
{
CompScreenPtr cs = GetCompScreen(pScreen);
WindowPtr pRoot = WindowTable[pScreen->myNum];
WindowPtr pRoot = pScreen->root;
WindowPtr pWin;
XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */
int result;
......
......@@ -234,8 +234,8 @@ FlushClientCaches(XID id)
{
if (client->lastDrawableID == id)
{
client->lastDrawableID = WindowTable[0]->drawable.id;
client->lastDrawable = (DrawablePtr)WindowTable[0];
client->lastDrawableID = screenInfo.screens[0]->root->drawable.id;
client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root;
}
else if (client->lastGCID == id)
{
......@@ -793,7 +793,7 @@ GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
rep->type = X_Reply;
rep->length = 0;
rep->sequenceNumber = client->sequence;
rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
rep->root = pDraw->pScreen->root->drawable.id;
rep->depth = pDraw->depth;
rep->width = pDraw->width;
rep->height = pDraw->height;
......@@ -854,7 +854,7 @@ ProcQueryTree(register ClientPtr client)
return(BadWindow);
memset(&reply, 0, sizeof(xQueryTreeReply));
reply.type = X_Reply;
reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
reply.root = pWin->drawable.pScreen->root->drawable.id;
reply.sequenceNumber = client->sequence;
if (pWin->parent)
reply.parent = pWin->parent->drawable.id;
......@@ -3633,8 +3633,8 @@ void InitClient(ClientPtr client, int i, void * ospriv)
if (i)
{
client->closeDownMode = DestroyAll;
client->lastDrawable = (DrawablePtr)WindowTable[0];
client->lastDrawableID = WindowTable[0]->drawable.id;
client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root;
client->lastDrawableID = screenInfo.screens[0]->root->drawable.id;
}
else
{
......@@ -3853,8 +3853,8 @@ SendConnSetup(register ClientPtr client, char *reason)
register unsigned int j;
register xDepth *pDepth;
root->currentInputMask = WindowTable[i]->eventMask |
wOtherEventMasks (WindowTable[i]);
root->currentInputMask = screenInfo.screens[i]->root->eventMask |
wOtherEventMasks (screenInfo.screens[i]->root);
pDepth = (xDepth *)(root + 1);
for (j = 0; j < root->nDepths; j++)
{
......
......@@ -413,9 +413,10 @@ XineramaCheckPhysLimits(
static Bool
XineramaSetWindowPntrs(WindowPtr pWin)
{
if(pWin == WindowTable[0]) {
memcpy(sprite.windows, WindowTable,
PanoramiXNumScreens*sizeof(WindowPtr));
if(pWin == screenInfo.screens[0]->root) {
int i;
for (i = 0; i < PanoramiXNumScreens; i++)
sprite.windows[i] = screenInfo.screens[i]->root;
} else {
PanoramiXRes *win;
int i;
......@@ -601,7 +602,7 @@ XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
sprite.hotShape = NullRegion;
sprite.confined = FALSE;
sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
sprite.confineWin = (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin;
XineramaCheckPhysLimits(sprite.current, generateEvents);
}
......@@ -797,7 +798,7 @@ CheckVirtualMotion(
qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
}
}
ROOT = WindowTable[sprite.hot.pScreen->myNum];
ROOT = sprite.hot.pScreen->root;
}
static void
......@@ -997,7 +998,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
*/
if (xE->u.u.type == MotionNotify)
XE_KBPTR.root =
WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
sprite.hotPhys.pScreen->root->drawable.id;
eventinfo.events = xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
......@@ -1160,7 +1161,7 @@ playmore:
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
}
else
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
TRUE, FALSE);
PostNewCursor();
}
......@@ -1178,7 +1179,7 @@ ScreenRestructured (ScreenPtr pScreen)
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
}
else
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
TRUE, FALSE);
}
#endif
......@@ -1976,7 +1977,7 @@ CheckMotion(xEvent *xE)
if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
{
sprite.hot.pScreen = sprite.hotPhys.pScreen;
ROOT = WindowTable[sprite.hot.pScreen->myNum];
ROOT = sprite.hot.pScreen->root;
}
sprite.hot.x = XE_KBPTR.rootX;
sprite.hot.y = XE_KBPTR.rootY;
......@@ -2034,13 +2035,12 @@ WindowsRestructured()
#ifdef PANORAMIX
/* This was added to support reconfiguration under Xdmx. The problem is
* that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
* that if the 0th screen (i.e., screenInfo.screens[0]->root) is moved to an origin
* other than 0,0, the information in the private sprite structure must
* be updated accordingly, or XYToWindow (and other routines) will not
* compute correctly. */
void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
{
ScreenPtr pScreen = win->drawable.pScreen;
GrabPtr grab;
if (noPanoramiXExtension) return;
......@@ -2067,7 +2067,7 @@ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
sprite.hotPhys.x = sprite.hotPhys.y = 0;
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
} else
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
TRUE, FALSE);
}
#endif
......@@ -2144,7 +2144,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y)
if(sprite.confineWin)
XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
else
XineramaConfineCursorToWindow(WindowTable[0], TRUE);
XineramaConfineCursorToWindow(screenInfo.screens[0]->root, TRUE);
/* if the pointer wasn't confined, the DDX won't get
told of the pointer warp so we reposition it here */
if(!syncEvents.playingEvents)
......@@ -2157,7 +2157,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y)
} else
#endif
if (newScreen != sprite.hotPhys.pScreen)
ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
ConfineCursorToWindow(newScreen->root, TRUE, FALSE);
}
#ifdef PANORAMIX
......@@ -2169,7 +2169,6 @@ XineramaPointInWindowIsVisible(
int y
)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
BoxRec box;
int i, xoff, yoff;
......@@ -2185,7 +2184,6 @@ XineramaPointInWindowIsVisible(
for(i = 1; i < PanoramiXNumScreens; i++) {
pWin = sprite.windows[i];
pScreen = pWin->drawable.pScreen;
x = xoff - panoramiXdataPtr[i].x;
y = yoff - panoramiXdataPtr[i].y;
......@@ -2231,7 +2229,7 @@ XineramaWarpPointer(ClientPtr client)
winX = source->drawable.x;
winY = source->drawable.y;
if(source == WindowTable[0]) {
if(source == screenInfo.screens[0]->root) {
winX -= panoramiXdataPtr[0].x;
winY -= panoramiXdataPtr[0].y;
}
......@@ -2247,7 +2245,7 @@ XineramaWarpPointer(ClientPtr client)
if (dest) {
x = dest->drawable.x;
y = dest->drawable.y;
if(dest == WindowTable[0]) {
if(dest == screenInfo.screens[0]->root) {
x -= panoramiXdataPtr[0].x;
y -= panoramiXdataPtr[0].y;
}
......@@ -2822,7 +2820,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
/* see comment in EnqueueEvents regarding the next three lines */
if (xE->u.u.type == MotionNotify)
XE_KBPTR.root =
WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
sprite.hotPhys.pScreen->root->drawable.id;
eventinfo.events = xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
......@@ -3356,11 +3354,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
/* Notify all the roots */
#ifdef PANORAMIX
if ( !noPanoramiXExtension )
FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root);
else
#endif
for (i=0; i<screenInfo.numScreens; i++)
FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[i]->root);
}
else
{
......@@ -3375,11 +3373,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
/* Notify all the roots */
#ifdef PANORAMIX
if ( !noPanoramiXExtension )
FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[0]->root);
else
#endif
for (i=0; i<screenInfo.numScreens; i++)
FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[i]->root);
if (toWin == PointerRootWin)
(void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
NotifyPointer, TRUE);
......@@ -3393,11 +3391,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
TRUE);
#ifdef PANORAMIX
if ( !noPanoramiXExtension )
FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root);
else
#endif
for (i=0; i<screenInfo.numScreens; i++)
FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[i]->root);
if (toWin->parent != NullWindow)
(void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
NotifyNonlinearVirtual, TRUE);
......
......@@ -89,7 +89,7 @@ AddExtension(char *name, int NumEvents, int NumErrors,
int i;
register ExtensionEntry *ext, **newexts;
if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
return((ExtensionEntry *) NULL);
if ((lastEvent + NumEvents > LAST_EVENT) ||
(unsigned)(lastError + NumErrors > LAST_ERROR))
......@@ -260,6 +260,7 @@ CloseDownExtensions()
for (i = NumExtensions - 1; i >= 0; i--)
{
if (extensions[i]->CloseDown)
(* extensions[i]->CloseDown)(extensions[i]);
NumExtensions = i;
xfree(extensions[i]->name);
......
......@@ -86,8 +86,6 @@ ClientPtr serverClient;
int currentMaxClients; /* current size of clients array */
long maxBigRequestSize = MAX_BIG_REQUEST_SIZE;
WindowPtr *WindowTable;
unsigned long globalSerialNumber = 0;
unsigned long serverGeneration = 0;
......@@ -161,3 +159,5 @@ int argcGlobal;
char **argvGlobal;
DDXPointRec dixScreenOrigins[MAXSCREENS];
char *ConnectionInfo;
......@@ -121,7 +121,6 @@ extern int InitClientPrivates(ClientPtr client);
extern void Dispatch(void);
char *ConnectionInfo;
xConnSetupPrefix connSetupPrefix;
extern FontPtr defaultFont;
......@@ -333,9 +332,6 @@ main(int argc, char *argv[], char *envp[])
screenInfo.arraySize = MAXSCREENS;
screenInfo.numScreens = 0;
screenInfo.numVideoScreens = -1;
WindowTable = (WindowPtr *)xalloc(MAXSCREENS * sizeof(WindowPtr));
if (!WindowTable)
FatalError("couldn't create root window table");
/*
* Just in case the ddx doesnt supply a format for depth 1 (like qvss).
......@@ -420,8 +416,8 @@ main(int argc, char *argv[], char *envp[])
#endif
for (i = 0; i < screenInfo.numScreens; i++)
InitRootWindow(WindowTable[i]);
DefineInitialRootWindow(WindowTable[0]);
InitRootWindow(screenInfo.screens[i]->root);
DefineInitialRootWindow(screenInfo.screens[0]->root);
SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
#ifdef DPMSExtension
SetDPMSTimers();
......@@ -457,7 +453,11 @@ main(int argc, char *argv[], char *envp[])
FreeAllResources();
#endif
for (i = 0; i < screenInfo.numScreens; i++)
screenInfo.screens[i]->root = NullWindow;
CloseDownDevices();
CloseDownEvents();
for (i = screenInfo.numScreens - 1; i >= 0; i--)
{
FreeScratchPixmapsForScreen(i);
......@@ -467,9 +467,6 @@ main(int argc, char *argv[], char *envp[])
FreeScreen(screenInfo.screens[i]);
screenInfo.numScreens = i;
}
CloseDownEvents();
xfree(WindowTable);
WindowTable = NULL;
FreeFonts();
#ifdef DPMSExtension
......@@ -596,7 +593,7 @@ CreateConnectionBlock()
VisualPtr pVisual;
pScreen = screenInfo.screens[i];
root.windowId = WindowTable[i]->drawable.id;
root.windowId = screenInfo.screens[i]->root->drawable.id;
root.defaultColormap = pScreen->defColormap;
root.whitePixel = pScreen->whitePixel;
root.blackPixel = pScreen->blackPixel;
......@@ -770,7 +767,6 @@ AddScreen(
multiple screens.
*/
pScreen->rgf = ~0L; /* there are no scratch GCs yet*/
WindowTable[i] = NullWindow;
screenInfo.screens[i] = pScreen;
screenInfo.numScreens++;
if (!(*pfnInit)(i, pScreen, argc, argv))
......@@ -785,6 +781,7 @@ AddScreen(
static void
FreeScreen(ScreenPtr pScreen)
{
pScreen->root = NullWindow;
xfree(pScreen->WindowPrivateSizes);
xfree(pScreen->GCPrivateSizes);
#ifdef PIXPRIV
......
......@@ -530,8 +530,6 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
RESTYPE rtype = res->type;
*prev = res->next;
elements = --*eltptr;
if (rtype & RC_CACHED)
FlushClientCaches(res->id);
if (rtype != skipDeleteFuncType)
(*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
xfree(res);
......@@ -542,11 +540,6 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
else
prev = &res->next;
}
if(clients[cid] && (id == clients[cid]->lastDrawableID))
{
clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
}
}
if (!gotOne)
ErrorF("Freeing resource id=%lX which isn't there.\n",
......@@ -570,8 +563,6 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
if (res->id == id && res->type == type)
{
*prev = res->next;
if (type & RC_CACHED)
FlushClientCaches(res->id);
if (!skipFree)
(*DeleteFuncs[type & TypeMask])(res->value, res->id);
xfree(res);
......@@ -580,11 +571,6 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
else
prev = &res->next;
}
if(clients[cid] && (id == clients[cid]->lastDrawableID))
{
clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
}
}
}
......@@ -607,8 +593,6 @@ ChangeResourceValue (XID id, RESTYPE rtype, void * value)
for (; res; res = res->next)
if ((res->id == id) && (res->type == rtype))
{
if (rtype & RC_CACHED)
FlushClientCaches(res->id);
res->value = value;
return TRUE;
}
......@@ -732,8 +716,6 @@ FreeClientNeverRetainResources(ClientPtr client)
if (rtype & RC_NEVERRETAIN)
{
*prev = this->next;
if (rtype & RC_CACHED)
FlushClientCaches(this->id);
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
xfree(this);
}
......@@ -778,8 +760,6 @@ FreeClientResources(ClientPtr client)
{
RESTYPE rtype = this->type;
*head = this->next;
if (rtype & RC_CACHED)
FlushClientCaches(this->id);
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
xfree(this);
}
......
......@@ -191,7 +191,7 @@ PrintWindowTree()
for (i=0; i<screenInfo.numScreens; i++)
{
ErrorF( "WINDOW %d\n", i);
pWin = WindowTable[i];
pWin = screenInfo.screens[i]->root;
RegionPrint(&pWin->clipList);
p1 = pWin->firstChild;
PrintChildren(p1, 4);
......@@ -237,7 +237,7 @@ TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, void * data)
int
WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void * data)
{
return(TraverseTree(WindowTable[pScreen->myNum], func, data));
return(TraverseTree(pScreen->root, func, data));
}
/* hack for forcing backing store on all windows */
......@@ -384,7 +384,7 @@ CreateRootWindow(ScreenPtr pScreen)
savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
screenIsSaved = SCREEN_SAVER_OFF;
WindowTable[pScreen->myNum] = pWin;
pScreen->root = pWin;
pWin->drawable.pScreen = pScreen;
pWin->drawable.type = DRAWABLE_WINDOW;
......@@ -1348,7 +1348,7 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt
*/
if ( cursorID == None)
{
if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
if (pWin == pWin->drawable.pScreen->root)
pCursor = rootCursor;
else
pCursor = (CursorPtr) None;
......@@ -3088,7 +3088,7 @@ HandleSaveSet(register ClientPtr client)
pWin = SaveSetWindow(client->saveSet[j]);
#ifdef XFIXES
if (SaveSetToRoot(client->saveSet[j]))
pParent = WindowTable[pWin->drawable.pScreen->myNum];
pParent = pWin->drawable.pScreen->root;
else
#endif
{
......@@ -3382,9 +3382,9 @@ TileScreenSaver(int i, int kind)
attri = 0;
switch (kind) {
case SCREEN_IS_TILED:
switch (WindowTable[i]->backgroundState) {
switch (screenInfo.screens[i]->root->backgroundState) {
case BackgroundPixel:
attributes[attri++] = WindowTable[i]->background.pixel;
attributes[attri++] = screenInfo.screens[i]->root->background.pixel;
mask |= CWBackPixel;
break;
case BackgroundPixmap:
......@@ -3396,7 +3396,7 @@ TileScreenSaver(int i, int kind)
}
break;
case SCREEN_IS_BLACK:
attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
attributes[attri++] = screenInfo.screens[i]->root->drawable.pScreen->blackPixel;
mask |= CWBackPixel;
break;
}
......@@ -3444,12 +3444,12 @@ TileScreenSaver(int i, int kind)
pWin = savedScreenInfo[i].pWindow =
CreateWindow(savedScreenInfo[i].wid,
WindowTable[i],
screenInfo.screens[i]->root,
-RANDOM_WIDTH, -RANDOM_WIDTH,
(unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
(unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
0, InputOutput, mask, attributes, 0, serverClient,
wVisual (WindowTable[i]), &result);
wVisual (screenInfo.screens[i]->root), &result);
if (cursor)
FreeResource (cursorID, RT_NONE);
......
......@@ -583,7 +583,6 @@ extern const GCFuncs fbGCFuncs;
#ifdef FB_OLD_SCREEN
# define FB_OLD_MISCREENINIT /* miScreenInit requires 14 args, not 13 */
extern WindowPtr *WindowTable;
#endif
#ifdef FB_24_32BIT
......@@ -704,7 +703,7 @@ typedef struct {
#define fbWindowEnabled(pWin) \
RegionNotEmpty(\
&WindowTable[(pWin)->drawable.pScreen->myNum]->borderClip)
&(pWin)->drawable.pScreen->root->borderClip)
#define fbDrawableEnabled(pDrawable) \
((pDrawable)->type == DRAWABLE_PIXMAP ? \
......
......@@ -262,7 +262,7 @@ fbFillRegionTiled (DrawablePtr pDrawable,
if(!noPanoramiXExtension)
{
int index = pDrawable->pScreen->myNum;
if(&WindowTable[index]->drawable == pDrawable)
if(&screenInfo.screens[index]->root->drawable == pDrawable)
{
xRot -= panoramiXdataPtr[index].x;
yRot -= panoramiXdataPtr[index].y;
......
......@@ -22,6 +22,7 @@
#include "Xatom.h"
#include "selection.h"
#include "windowstr.h"
#include "scrnintstr.h"
#include "Windows.h"
#include "Atoms.h"
......@@ -255,7 +256,7 @@ void nxagentClearSelection(XEvent *X)
NullGrab);
}
CurrentSelections[i].window = WindowTable[0]->drawable.id;
CurrentSelections[i].window = screenInfo.screens[0]->root->drawable.id;
CurrentSelections[i].client = NullClient;
lastSelectionOwner[i].client = NULL;
......@@ -424,7 +425,7 @@ FIXME: Do we need this?
* Fictitious window.
*/
x.u.selectionRequest.requestor = WindowTable[0]->drawable.id;
x.u.selectionRequest.requestor = screenInfo.screens[0]->root->drawable.id;
/*
* Don't send the same window, some programs are
......@@ -1502,13 +1503,13 @@ int nxagentInitClipboard(WindowPtr pWin)
lastSelectionOwner[nxagentPrimarySelection].selection = XA_PRIMARY;
lastSelectionOwner[nxagentPrimarySelection].client = NullClient;
lastSelectionOwner[nxagentPrimarySelection].window = WindowTable[0]->drawable.id;
lastSelectionOwner[nxagentPrimarySelection].window = screenInfo.screens[0]->root->drawable.id;
lastSelectionOwner[nxagentPrimarySelection].windowPtr = NULL;
lastSelectionOwner[nxagentPrimarySelection].lastTimeChanged = GetTimeInMillis();
lastSelectionOwner[nxagentClipboardSelection].selection = nxagentClipboardAtom;
lastSelectionOwner[nxagentClipboardSelection].client = NullClient;
lastSelectionOwner[nxagentClipboardSelection].window = WindowTable[0]->drawable.id;
lastSelectionOwner[nxagentClipboardSelection].window = screenInfo.screens[0]->root->drawable.id;
lastSelectionOwner[nxagentClipboardSelection].windowPtr = NULL;
lastSelectionOwner[nxagentClipboardSelection].lastTimeChanged = GetTimeInMillis();
......
......@@ -125,7 +125,7 @@ void nxagentRedirectDefaultWindows()
for (i = 0; i < screenInfo.numScreens; i++)
{
WindowPtr pWin = WindowTable[i];
WindowPtr pWin = screenInfo.screens[i]->root;
ScreenPtr pScreen = pWin -> drawable.pScreen;
......
......@@ -3292,7 +3292,7 @@ void nxagentSendDeferredBackgroundExposures(void)
fprintf(stderr, "nxagentSendDeferredBackgroundExposures: Going to send deferred exposures to the root window.\n");
#endif
TraverseTree(WindowTable[0], nxagentClipAndSendClearExpose, (void *) nxagentDeferredBackgroundExposures);
TraverseTree(screenInfo.screens[0]->root, nxagentClipAndSendClearExpose, (void *) nxagentDeferredBackgroundExposures);
RegionEmpty(nxagentDeferredBackgroundExposures);
}
......
......@@ -629,8 +629,8 @@ void nxagentShadowSwitchResizeMode(ScreenPtr pScreen)
{
nxagentShadowSetRatio(1.0, 1.0);
nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], WindowTable[0],
WindowTable[0] -> drawable.width, WindowTable[0] -> drawable.height);
nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], screenInfo.screens[0]->root,
screenInfo.screens[0]->root -> drawable.width, screenInfo.screens[0]->root -> drawable.height);
sizeHints.max_width = nxagentOption(RootWidth);
sizeHints.max_height = nxagentOption(RootHeight);
......@@ -640,13 +640,13 @@ void nxagentShadowSwitchResizeMode(ScreenPtr pScreen)
else
{
nxagentShadowSetRatio(nxagentOption(Width) * 1.0 /
WindowTable[0] -> drawable.width,
screenInfo.screens[0]->root -> drawable.width,
nxagentOption(Height) * 1.0 /
WindowTable[0] -> drawable.height);
screenInfo.screens[0]->root -> drawable.height);
nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)],
WindowTable[0], WindowTable[0] -> drawable.width,
WindowTable[0] -> drawable.height);
screenInfo.screens[0]->root, screenInfo.screens[0]->root -> drawable.width,
screenInfo.screens[0]->root -> drawable.height);
sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
......@@ -963,10 +963,10 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
case doDebugTree:
{
fprintf(stderr, "\n ========== nxagentRemoteWindowsTree ==========\n");
nxagentRemoteWindowsTree(nxagentWindow(WindowTable[0]), 0);
nxagentRemoteWindowsTree(nxagentWindow(screenInfo.screens[0]->root), 0);
fprintf(stderr, "\n========== nxagentInternalWindowsTree ==========\n");
nxagentInternalWindowsTree(WindowTable[0], 0);
nxagentInternalWindowsTree(screenInfo.screens[0]->root, 0);
break;
}
......@@ -1405,7 +1405,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
(X.xmotion.y_root < nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
{
if (pWin && nxagentClientIsDialog(wClient(pWin)) == 0 &&
nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
nxagentLastEnteredTopLevelWindow -> parent == screenInfo.screens[0]->root &&
nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
(nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
......@@ -1625,7 +1625,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
if (pWin != NULL)
{
for (pTLWin = pWin;
pTLWin -> parent != WindowTable[pTLWin -> drawable.pScreen -> myNum];
pTLWin -> parent != pTLWin -> drawable.pScreen -> root;
pTLWin = pTLWin -> parent);
}
......@@ -2454,7 +2454,7 @@ FIXME: This can be maybe optimized by consuming the
RegionValidate(&sum, &overlap);
RegionIntersect(&sum, &sum,
&WindowTable[pWin->drawable.pScreen->myNum]->winSize);
&pWin->drawable.pScreen->root->winSize);
#ifdef DEBUG
fprintf(stderr, "nxagentHandleExposeEvent: Sending events for window id [%ld].\n",
......@@ -3147,7 +3147,7 @@ int nxagentCheckWindowConfiguration(XConfigureEvent* X)
fprintf(stderr, "nxagentCheckWindowConfiguration: Before restacking top level window [%p]\n",
(void *) nxagentWindowPtr(X -> window));
for (pSib = WindowTable[0] -> firstChild; pSib; pSib = pSib -> nextSib)
for (pSib = screenInfo.screens[0]->root -> firstChild; pSib; pSib = pSib -> nextSib)
{
fprintf(stderr, "nxagentCheckWindowConfiguration: Top level window: [%p].\n",
(void *) pSib);
......@@ -3431,7 +3431,7 @@ int nxagentHandleConfigureNotify(XEvent* X)
nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
nxagentOption(RootHeight));
XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root),
nxagentOption(RootX), nxagentOption(RootY));
}
......@@ -4245,7 +4245,7 @@ void nxagentForwardRemoteExpose(void)
fprintf(stderr, "nxagentForwardRemoteExpose: Going to forward events.\n");
#endif
TraverseTree(WindowTable[0], nxagentClipAndSendExpose, (void *)nxagentRemoteExposeRegion);
TraverseTree(screenInfo.screens[0]->root, nxagentClipAndSendExpose, (void *)nxagentRemoteExposeRegion);
/*
* Now this region should be empty.
......@@ -4420,7 +4420,7 @@ int nxagentHandleRRScreenChangeNotify(XEvent *X)
nxagentResizeScreen(screenInfo.screens[DefaultScreen(nxagentDisplay)], Xr -> width, Xr -> height,
Xr -> mwidth, Xr -> mheight);
nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], WindowTable[0],
nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], screenInfo.screens[0]->root,
Xr -> width, Xr -> height);
nxagentShadowSetWindowsSize();
......
......@@ -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
......
......@@ -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
......
......@@ -344,13 +344,13 @@ InitSelections()
CurrentSelections[0].selection = XA_PRIMARY;
CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
CurrentSelections[0].window = WindowTable[0]->drawable.id;
CurrentSelections[0].window = screenInfo.screens[0]->root->drawable.id;
CurrentSelections[0].pWin = NULL;
CurrentSelections[0].client = NullClient;
CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
CurrentSelections[1].window = WindowTable[0]->drawable.id;
CurrentSelections[1].window = screenInfo.screens[0]->root->drawable.id;
CurrentSelections[1].pWin = NULL;
CurrentSelections[1].client = NullClient;
}
......@@ -374,8 +374,8 @@ FlushClientCaches(XID id)
{
if (client->lastDrawableID == id)
{
client->lastDrawableID = WindowTable[0]->drawable.id;
client->lastDrawable = (DrawablePtr)WindowTable[0];
client->lastDrawableID = screenInfo.screens[0]->root->drawable.id;
client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root;
}
else if (client->lastGCID == id)
{
......@@ -1161,7 +1161,7 @@ GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
rep->type = X_Reply;
rep->length = 0;
rep->sequenceNumber = client->sequence;
rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
rep->root = pDraw->pScreen->root->drawable.id;
rep->depth = pDraw->depth;
rep->width = pDraw->width;
rep->height = pDraw->height;
......@@ -1221,7 +1221,7 @@ ProcQueryTree(register ClientPtr client)
return(BadWindow);
memset(&reply, 0, sizeof(xQueryTreeReply));
reply.type = X_Reply;
reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
reply.root = pWin->drawable.pScreen->root->drawable.id;
reply.sequenceNumber = client->sequence;
if (pWin->parent)
reply.parent = pWin->parent->drawable.id;
......@@ -4319,8 +4319,8 @@ void InitClient(ClientPtr client, int i, void * ospriv)
if (i)
{
client->closeDownMode = DestroyAll;
client->lastDrawable = (DrawablePtr)WindowTable[0];
client->lastDrawableID = WindowTable[0]->drawable.id;
client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root;
client->lastDrawableID = screenInfo.screens[0]->root->drawable.id;
}
else
{
......@@ -4563,8 +4563,8 @@ SendConnSetup(register ClientPtr client, char *reason)
register unsigned int j;
register xDepth *pDepth;
root->currentInputMask = WindowTable[i]->eventMask |
wOtherEventMasks (WindowTable[i]);
root->currentInputMask = screenInfo.screens[i]->root->eventMask |
wOtherEventMasks (screenInfo.screens[i]->root);
pDepth = (xDepth *)(root + 1);
for (j = 0; j < root->nDepths; j++)
{
......
......@@ -162,7 +162,6 @@ extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
#endif
#ifdef XEVIE
extern WindowPtr *WindowTable;
extern int xevieFlag;
extern int xevieClientIndex;
extern DeviceIntPtr xeviemouse;
......@@ -465,9 +464,10 @@ XineramaCheckPhysLimits(
static Bool
XineramaSetWindowPntrs(WindowPtr pWin)
{
if(pWin == WindowTable[0]) {
memcpy(sprite.windows, WindowTable,
PanoramiXNumScreens*sizeof(WindowPtr));
if(pWin == screenInfo.screens[0]->root) {
int i;
for (i = 0; i < PanoramiXNumScreens; i++)
sprite.windows[i] = screenInfo.screens[i]->root;
} else {
PanoramiXRes *win;
int i;
......@@ -692,7 +692,7 @@ XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
sprite.hotShape = NullRegion;
sprite.confined = FALSE;
sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
sprite.confineWin = (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin;
XineramaCheckPhysLimits(sprite.current, generateEvents);
}
......@@ -909,7 +909,7 @@ CheckVirtualMotion(
qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
}
}
ROOT = WindowTable[sprite.hot.pScreen->myNum];
ROOT = sprite.hot.pScreen->root;
}
static void
......@@ -1109,7 +1109,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
*/
if (xE->u.u.type == MotionNotify)
XE_KBPTR.root =
WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
sprite.hotPhys.pScreen->root->drawable.id;
eventinfo.events = xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
......@@ -1272,7 +1272,7 @@ playmore:
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
}
else
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
TRUE, FALSE);
PostNewCursor();
}
......@@ -1290,7 +1290,7 @@ ScreenRestructured (ScreenPtr pScreen)
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
}
else
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
TRUE, FALSE);
}
#endif
......@@ -2219,7 +2219,7 @@ CheckMotion(xEvent *xE)
if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
{
sprite.hot.pScreen = sprite.hotPhys.pScreen;
ROOT = WindowTable[sprite.hot.pScreen->myNum];
ROOT = sprite.hot.pScreen->root;
}
#ifdef XEVIE
xeviehot.x =
......@@ -2307,9 +2307,9 @@ WindowsRestructured()
#ifdef PANORAMIX
/* This was added to support reconfiguration under Xdmx. The problem is
* that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
* other than 0,0, the information in the private sprite structure must
* be updated accordingly, or XYToWindow (and other routines) will not
* that if the 0th screen (i.e., screenInfo.screens[0]->root) is moved to
* an origin other than 0,0, the information in the private sprite structure
* must be updated accordingly, or XYToWindow (and other routines) will not
* compute correctly. */
void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
{
......@@ -2339,7 +2339,7 @@ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
sprite.hotPhys.x = sprite.hotPhys.y = 0;
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
} else
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
TRUE, FALSE);
}
#endif
......@@ -2435,7 +2435,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y)
if(sprite.confineWin)
XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
else
XineramaConfineCursorToWindow(WindowTable[0], TRUE);
XineramaConfineCursorToWindow(screenInfo.screens[0]->root, TRUE);
/* if the pointer wasn't confined, the DDX won't get
told of the pointer warp so we reposition it here */
if(!syncEvents.playingEvents)
......@@ -2448,7 +2448,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y)
} else
#endif
if (newScreen != sprite.hotPhys.pScreen)
ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
ConfineCursorToWindow(newScreen->root, TRUE, FALSE);
}
#ifdef PANORAMIX
......@@ -2520,7 +2520,7 @@ XineramaWarpPointer(ClientPtr client)
winX = source->drawable.x;
winY = source->drawable.y;
if(source == WindowTable[0]) {
if(source == screenInfo.screens[0]->root) {
winX -= panoramiXdataPtr[0].x;
winY -= panoramiXdataPtr[0].y;
}
......@@ -2536,7 +2536,7 @@ XineramaWarpPointer(ClientPtr client)
if (dest) {
x = dest->drawable.x;
y = dest->drawable.y;
if(dest == WindowTable[0]) {
if(dest == screenInfo.screens[0]->root) {
x -= panoramiXdataPtr[0].x;
y -= panoramiXdataPtr[0].y;
}
......@@ -3206,7 +3206,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
/* see comment in EnqueueEvents regarding the next three lines */
if (xE->u.u.type == MotionNotify)
XE_KBPTR.root =
WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
sprite.hotPhys.pScreen->root->drawable.id;
eventinfo.events = xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
......@@ -3818,11 +3818,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
/* Notify all the roots */
#ifdef PANORAMIX
if ( !noPanoramiXExtension )
FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root);
else
#endif
for (i=0; i<screenInfo.numScreens; i++)
FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[i]->root);
}
else
{
......@@ -3837,11 +3837,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
/* Notify all the roots */
#ifdef PANORAMIX
if ( !noPanoramiXExtension )
FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[0]->root);
else
#endif
for (i=0; i<screenInfo.numScreens; i++)
FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[i]->root);
if (toWin == PointerRootWin)
(void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
NotifyPointer, TRUE);
......@@ -3855,11 +3855,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
TRUE);
#ifdef PANORAMIX
if ( !noPanoramiXExtension )
FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root);
else
#endif
for (i=0; i<screenInfo.numScreens; i++)
FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[i]->root);
if (toWin->parent != NullWindow)
(void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
NotifyNonlinearVirtual, TRUE);
......
......@@ -111,7 +111,7 @@ AddExtension(char *name, int NumEvents, int NumErrors,
int i;
register ExtensionEntry *ext, **newexts;
if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
return((ExtensionEntry *) NULL);
if ((lastEvent + NumEvents > LAST_EVENT) ||
(unsigned)(lastError + NumErrors > LAST_ERROR))
......@@ -296,6 +296,7 @@ CloseDownExtensions()
for (i = NumExtensions - 1; i >= 0; i--)
{
if (extensions[i]->CloseDown)
(* extensions[i]->CloseDown)(extensions[i]);
NumExtensions = i;
xfree(extensions[i]->name);
......
......@@ -504,7 +504,7 @@ miSendExposures(pWin, pRgn, dx, dy)
if(!pWin->parent) {
x = panoramiXdataPtr[scrnum].x;
y = panoramiXdataPtr[scrnum].y;
pWin = WindowTable[0];
pWin = screenInfo.screens[0]->root;
realWin = pWin->drawable.id;
} else if (scrnum) {
PanoramiXRes *win;
......@@ -788,7 +788,7 @@ int what;
gcmask |= GCFunction | GCClipMask;
i = pScreen->myNum;
pRoot = WindowTable[i];
pRoot = screenInfo.screens[i]->root;
pBgWin = pWin;
if (what == PW_BORDER)
......
......@@ -2051,74 +2051,6 @@ AddTraps (PicturePtr pPicture,
(*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
}
#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
Bool
PictureTransformPoint3d (PictTransformPtr transform,
PictVectorPtr vector)
{
PictVector result;
int i, j;
xFixed_32_32 partial;
xFixed_48_16 v;
for (j = 0; j < 3; j++)
{
v = 0;
for (i = 0; i < 3; i++)
{
partial = ((xFixed_48_16) transform->matrix[j][i] *
(xFixed_48_16) vector->vector[i]);
v += partial >> 16;
}
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
return FALSE;
result.vector[j] = (xFixed) v;
}
if (!result.vector[2])
return FALSE;
*vector = result;
return TRUE;
}
Bool
PictureTransformPoint (PictTransformPtr transform,
PictVectorPtr vector)
{
PictVector result;
int i, j;
xFixed_32_32 partial;
xFixed_48_16 v;
for (j = 0; j < 3; j++)
{
v = 0;
for (i = 0; i < 3; i++)
{
partial = ((xFixed_48_16) transform->matrix[j][i] *
(xFixed_48_16) vector->vector[i]);
v += partial >> 16;
}
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
return FALSE;
result.vector[j] = (xFixed) v;
}
if (!result.vector[2])
return FALSE;
for (j = 0; j < 2; j++)
{
partial = (xFixed_48_16) result.vector[j] << 16;
v = partial / result.vector[2];
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
return FALSE;
vector->vector[j] = (xFixed) v;
}
vector->vector[2] = xFixed1;
return TRUE;
}
#ifndef True
# define True 1
#endif
......
......@@ -78,13 +78,10 @@ typedef struct _PictFormat {
IndexFormatRec index;
} PictFormatRec;
typedef struct _PictVector {
xFixed vector[3];
} PictVector, *PictVectorPtr;
typedef struct pixman_vector PictVector, *PictVectorPtr;
typedef struct pixman_transform PictTransform, *PictTransformPtr;
typedef struct _PictTransform {
xFixed matrix[3][3];
} PictTransform, *PictTransformPtr;
#define pict_f_transform pixman_f_transform
#define PICT_GRADIENT_STOPTABLE_SIZE 1024
#define SourcePictTypeSolidFill 0
......@@ -193,12 +190,14 @@ typedef struct _Picture {
SourcePictPtr pSourcePict;
} PictureRec;
typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
xFixed *params, int nparams);
typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id,
xFixed *params, int nparams,
int *width, int *height);
typedef struct {
char *name;
int id;
PictFilterValidateParamsProcPtr ValidateParams;
int width, height;
} PictFilterRec, *PictFilterPtr;
#define PictFilterNearest 0
......@@ -482,7 +481,12 @@ PictFilterPtr
PictureFindFilter (ScreenPtr pScreen, char *name, int len);
int
SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
xFixed *params, int nparams);
int
SetPictureFilter (PicturePtr pPicture, char *name, int len,
xFixed *params, int nparams);
Bool
PictureFinishInit (void);
......@@ -682,4 +686,22 @@ void PanoramiXRenderInit (void);
void PanoramiXRenderReset (void);
#endif
/*
* matrix.c
*/
extern _X_EXPORT void
PictTransform_from_xRenderTransform(PictTransformPtr pict,
xRenderTransform * render);
extern _X_EXPORT void
xRenderTransform_from_PictTransform(xRenderTransform * render,
PictTransformPtr pict);
extern _X_EXPORT Bool
PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector);
extern _X_EXPORT Bool
PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector);
#endif /* _PICTURESTR_H_ */
......@@ -3204,7 +3204,7 @@ PanoramiXRenderCreatePicture (ClientPtr client)
newPict->info[0].id = stuff->pid;
if (refDraw->type == XRT_WINDOW &&
stuff->drawable == WindowTable[0]->drawable.id)
stuff->drawable == screenInfo.screens[0]->root->drawable.id)
{
newPict->u.pict.root = TRUE;
}
......
......@@ -685,8 +685,6 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
#ifdef NXAGENT_SERVER
nxagentResChangedFlag = 1;
#endif
if (rtype & RC_CACHED)
FlushClientCaches(res->id);
if (rtype != skipDeleteFuncType)
(*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
xfree(res);
......@@ -697,11 +695,6 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
else
prev = &res->next;
}
if(clients[cid] && (id == clients[cid]->lastDrawableID))
{
clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
}
}
if (!gotOne)
ErrorF("Freeing resource id=%lX which isn't there.\n",
......@@ -728,8 +721,6 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
#ifdef NXAGENT_SERVER
nxagentResChangedFlag = 1;
#endif
if (type & RC_CACHED)
FlushClientCaches(res->id);
if (!skipFree)
(*DeleteFuncs[type & TypeMask])(res->value, res->id);
xfree(res);
......@@ -738,11 +729,6 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
else
prev = &res->next;
}
if(clients[cid] && (id == clients[cid]->lastDrawableID))
{
clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
}
}
}
......@@ -765,8 +751,6 @@ ChangeResourceValue (XID id, RESTYPE rtype, void * value)
for (; res; res = res->next)
if ((res->id == id) && (res->type == rtype))
{
if (rtype & RC_CACHED)
FlushClientCaches(res->id);
res->value = value;
return TRUE;
}
......@@ -1027,8 +1011,6 @@ FreeClientNeverRetainResources(ClientPtr client)
if (rtype & RC_NEVERRETAIN)
{
*prev = this->next;
if (rtype & RC_CACHED)
FlushClientCaches(this->id);
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
xfree(this);
}
......@@ -1073,8 +1055,6 @@ FreeClientResources(ClientPtr client)
{
RESTYPE rtype = this->type;
*head = this->next;
if (rtype & RC_CACHED)
FlushClientCaches(this->id);
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
xfree(this);
}
......
......@@ -240,7 +240,7 @@ PrintWindowTree()
for (i=0; i<screenInfo.numScreens; i++)
{
ErrorF( "WINDOW %d\n", i);
pWin = WindowTable[i];
pWin = screenInfo.screens[i]->root;
RegionPrint(&pWin->clipList);
p1 = pWin->firstChild;
PrintChildren(p1, 4);
......@@ -286,7 +286,7 @@ TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, void * data)
int
WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void * data)
{
return(TraverseTree(WindowTable[pScreen->myNum], func, data));
return(TraverseTree(pScreen->root, func, data));
}
/* hack for forcing backing store on all windows */
......@@ -457,7 +457,9 @@ CreateRootWindow(ScreenPtr pScreen)
savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
screenIsSaved = SCREEN_SAVER_OFF;
WindowTable[pScreen->myNum] = pWin;
pScreen->root = pWin;
pScreen->root = pWin;
pWin->drawable.pScreen = pScreen;
pWin->drawable.type = DRAWABLE_WINDOW;
......@@ -583,11 +585,11 @@ InitRootWindow(WindowPtr pWin)
/*
* A root window is created for each screen by main
* and the pointer is saved in WindowTable as in the
* following snippet:
* and the pointer is saved in screenInfo.screens as
* in the following snippet:
*
* for (i = 0; i < screenInfo.numScreens; i++)
* InitRootWindow(WindowTable[i]);
* InitRootWindow(screenInfo.screens[i]->root);
*
* Our root window on the real display was already
* created at the time the screen was opened, so it
......@@ -1583,7 +1585,7 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt
*/
if ( cursorID == None)
{
if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
if (pWin == pWin->drawable.pScreen->root)
pCursor = rootCursor;
else
pCursor = (CursorPtr) None;
......@@ -2863,7 +2865,7 @@ ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
pWin->parent = pParent;
pPrev = RealChildHead(pParent);
if (pWin->parent == WindowTable[0])
if (pWin->parent == screenInfo.screens[0]->root)
{
nxagentSetTopLevelEventMask(pWin);
}
......@@ -3442,7 +3444,7 @@ HandleSaveSet(register ClientPtr client)
pWin = SaveSetWindow(client->saveSet[j]);
#ifdef XFIXES
if (SaveSetToRoot(client->saveSet[j]))
pParent = WindowTable[pWin->drawable.pScreen->myNum];
pParent = pWin->drawable.pScreen->root;
else
#endif
{
......@@ -3744,9 +3746,9 @@ TileScreenSaver(int i, int kind)
attri = 0;
switch (kind) {
case SCREEN_IS_TILED:
switch (WindowTable[i]->backgroundState) {
switch (screenInfo.screens[i]->root->backgroundState) {
case BackgroundPixel:
attributes[attri++] = WindowTable[i]->background.pixel;
attributes[attri++] = screenInfo.screens[i]->root->background.pixel;
mask |= CWBackPixel;
break;
case BackgroundPixmap:
......@@ -3758,7 +3760,7 @@ TileScreenSaver(int i, int kind)
}
break;
case SCREEN_IS_BLACK:
attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
attributes[attri++] = screenInfo.screens[i]->root->drawable.pScreen->blackPixel;
mask |= CWBackPixel;
break;
}
......@@ -3806,12 +3808,12 @@ TileScreenSaver(int i, int kind)
pWin = savedScreenInfo[i].pWindow =
CreateWindow(savedScreenInfo[i].wid,
WindowTable[i],
screenInfo.screens[i]->root,
-RANDOM_WIDTH, -RANDOM_WIDTH,
(unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
(unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
0, InputOutput, mask, attributes, 0, serverClient,
wVisual (WindowTable[i]), &result);
wVisual (screenInfo.screens[i]->root), &result);
if (cursor)
FreeResource (cursorID, RT_NONE);
......
......@@ -1449,7 +1449,7 @@ Bool nxagentFbOnShadowDisplay()
XGCValues value;
XImage *image;
Visual *pVisual;
WindowPtr pWin = WindowTable[0];
WindowPtr pWin = screenInfo.screens[0]->root;
unsigned int format;
int depth, width, height, length;
char *data = NULL;
......
......@@ -20,6 +20,7 @@
#include "../../include/window.h"
#include "windowstr.h"
#include "colormapst.h"
#include "scrnintstr.h"
#include "propertyst.h"
#include "Agent.h"
......@@ -242,7 +243,7 @@ Bool nxagentRootlessTreesMatch()
Window *children_return;
unsigned int nChildrenReturn;
WindowPtr pW;
WindowPtr pTestWin = WindowTable[0] -> firstChild;
WindowPtr pTestWin = screenInfo.screens[0]->root -> firstChild;
Bool treesMatch = True;
Status result;
......@@ -267,7 +268,7 @@ Bool nxagentRootlessTreesMatch()
pW = nxagentRootlessTopLevelWindow(children_return[nChildrenReturn]);
}
if (pW && pW != WindowTable[0])
if (pW && pW != screenInfo.screens[0]->root)
{
if (treesMatch && pTestWin && pTestWin == pW)
{
......@@ -316,7 +317,7 @@ void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren)
pWin = nxagentRootlessTopLevelWindow(children[i]);
}
if (pWin && pWin != WindowTable[0])
if (pWin && pWin != screenInfo.screens[0]->root)
{
toplevel[ntoplevel++] = pWin;
}
......@@ -338,14 +339,14 @@ void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren)
fprintf(stderr, "nxagentRootlessRestack: Internal top level windows before restack:");
for (pWin = WindowTable[0] -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
for (pWin = screenInfo.screens[0]->root -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
{
fprintf(stderr, "[%p]\n", pWin);
}
#endif
pWin = WindowTable[0] -> firstChild;
pWin = screenInfo.screens[0]->root -> firstChild;
values[1] = (XID) Above;
......@@ -381,7 +382,7 @@ void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren)
fprintf(stderr, "nxagentRootlessRestack: Internal top level windows after restack:");
for (pWin = WindowTable[0] -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
for (pWin = screenInfo.screens[0]->root -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
{
fprintf(stderr, "[%p]\n", pWin);
}
......
......@@ -2116,7 +2116,7 @@ Bool nxagentCloseScreen(int index, ScreenPtr pScreen)
static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
WindowPtr pWin = pScreen->root;
WindowPtr pChild;
Bool WasViewable = (Bool)(pWin->viewable);
Bool anyMarked = FALSE;
......@@ -2409,21 +2409,21 @@ FIXME: We should try to restore the previously
box.x2 = width;
box.y2 = height;
WindowTable[pScreen -> myNum] -> drawable.width = width;
WindowTable[pScreen -> myNum] -> drawable.height = height;
WindowTable[pScreen -> myNum] -> drawable.x = 0;
WindowTable[pScreen -> myNum] -> drawable.y = 0;
pScreen->root -> drawable.width = width;
pScreen->root -> drawable.height = height;
pScreen->root -> drawable.x = 0;
pScreen->root -> drawable.y = 0;
RegionInit(&WindowTable[pScreen -> myNum] -> borderSize, &box, 1);
RegionInit(&WindowTable[pScreen -> myNum] -> winSize, &box, 1);
RegionInit(&WindowTable[pScreen -> myNum] -> clipList, &box, 1);
RegionInit(&WindowTable[pScreen -> myNum] -> borderClip, &box, 1);
RegionInit(&pScreen->root -> borderSize, &box, 1);
RegionInit(&pScreen->root -> winSize, &box, 1);
RegionInit(&pScreen->root -> clipList, &box, 1);
RegionInit(&pScreen->root -> borderClip, &box, 1);
(*pScreen -> PositionWindow)(WindowTable[pScreen -> myNum], 0, 0);
(*pScreen -> PositionWindow)(pScreen->root, 0, 0);
nxagentSetRootClip(pScreen, 1);
XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[0]),
XMoveWindow(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root),
nxagentOption(RootX), nxagentOption(RootY));
nxagentMoveViewport(pScreen, 0, 0);
......@@ -3522,7 +3522,7 @@ FIXME: The port information is not used at the moment and produces a
{
mcop_local_atom = MakeAtom(mcop_atom, strlen(mcop_atom), 1);
ChangeWindowProperty(WindowTable[pScreen->myNum],
ChangeWindowProperty(pScreen->root,
mcop_local_atom,
XA_STRING,
iReturnFormat, PropModeReplace,
......@@ -3667,9 +3667,9 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in
int r;
#ifdef TEST
fprintf(stderr, "nxagentChangeScreenConfig: WindowTable[%d] is %p\n", screen, WindowTable[screen]);
fprintf(stderr, "nxagentChangeScreenConfig: screenInfo.screens[%d]->root is %p\n", screen, screenInfo.screens[screen]);
#endif
if (WindowTable[screen] == NULL)
if (screenInfo.screens[screen]->root == NULL)
{
return 0;
}
......@@ -3692,7 +3692,7 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in
return 0;
}
pScreen = WindowTable[screen] -> drawable.pScreen;
pScreen = screenInfo.screens[screen] -> root -> drawable.pScreen;
#ifdef TEST
fprintf(stderr, "nxagentChangeScreenConfig: Changing config to %dx%d.\n", width, height);
......@@ -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);
}
......@@ -4124,7 +4124,7 @@ void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg,
values.subwindow_mode = IncludeInferiors;
gc = XCreateGC(nxagentDisplay, nxagentWindow(WindowTable[0]), GCSubwindowMode, &values);
gc = XCreateGC(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root), GCSubwindowMode, &values);
/*
* Initialize to the corrupted region.
......@@ -4234,7 +4234,7 @@ void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg,
*/
RegionIntersect(prgnRestore, prgnRestore,
&WindowTable[pWin -> drawable.pScreen -> myNum] -> winSize);
&pWin -> drawable.pScreen -> root -> winSize);
pBackingStore = (miBSWindowPtr) pWin -> backStorage;
......@@ -4245,7 +4245,7 @@ void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg,
values.subwindow_mode = ClipByChildren;
gc = XCreateGC(nxagentDisplay, nxagentWindow(WindowTable[0]), GCSubwindowMode, &values);
gc = XCreateGC(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root), GCSubwindowMode, &values);
/*
* Translate the reference point to the origin of the window.
......@@ -4406,7 +4406,7 @@ void nxagentShadowAdaptToRatio(void)
nxagentShadowSetRatio(nxagentOption(Width) * 1.0 / nxagentShadowWidth,
nxagentOption(Height) * 1.0 / nxagentShadowHeight);
nxagentShadowCreateMainWindow(pScreen, WindowTable[0], nxagentShadowWidth, nxagentShadowHeight);
nxagentShadowCreateMainWindow(pScreen, screenInfo.screens[0]->root, nxagentShadowWidth, nxagentShadowHeight);
sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
......@@ -4456,7 +4456,7 @@ void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height)
XlibGC gc;
XGCValues value;
XImage *image;
WindowPtr pWin = WindowTable[0];
WindowPtr pWin = screenInfo.screens[0]->root;
unsigned int format;
int depth, pixmapWidth, pixmapHeight, length;
char *data;
......@@ -4668,7 +4668,7 @@ FIXME
value.fill_style = FillSolid;
value.function = GXcopy;
gc = XCreateGC(shadow, nxagentWindow(WindowTable[0]), GCBackground |
gc = XCreateGC(shadow, nxagentWindow(screenInfo.screens[0]->root), GCBackground |
GCForeground | GCFillStyle | GCPlaneMask | GCFunction, &value);
NXCleanImage(image);
......
......@@ -396,15 +396,15 @@ void nxagentRemoveSplashWindow(WindowPtr pWin)
XDestroyWindow(nxagentDisplay, nxagentSplashWindow);
nxagentSplashWindow = None;
nxagentRefreshWindows(WindowTable[0]);
nxagentRefreshWindows(screenInfo.screens[0]->root);
#ifdef TEST
fprintf(stderr, "nxagentRemoveSplashWindow: setting the ownership of %s (%d) on window 0x%lx\n",
"NX_CUT_BUFFER_SERVER", (int)serverCutProperty, nxagentWindow(WindowTable[0]));
"NX_CUT_BUFFER_SERVER", (int)serverCutProperty, nxagentWindow(screenInfo.screens[0]->root));
#endif
XSetSelectionOwner(nxagentDisplay, serverCutProperty,
nxagentWindow(WindowTable[0]), CurrentTime);
nxagentWindow(screenInfo.screens[0]->root), CurrentTime);
}
if (nxagentPixmapLogo)
......
......@@ -196,7 +196,7 @@ static Bool nxagentCheckWindowIntegrity(WindowPtr pWin);
WindowPtr nxagentGetWindowFromID(Window id)
{
WindowPtr pWin = WindowTable[0];
WindowPtr pWin = screenInfo.screens[0]->root;
while (pWin && nxagentWindowPriv(pWin))
{
......@@ -508,7 +508,7 @@ FIXME: Do all the windows for which nxagentWindowTopLevel(pWin)
Bool nxagentSomeWindowsAreMapped()
{
WindowPtr pWin = WindowTable[0] -> firstChild;
WindowPtr pWin = screenInfo.screens[0]->root -> firstChild;
while (pWin)
{
......@@ -884,7 +884,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight));
XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root),
nxagentOption(RootX), nxagentOption(RootY));
/*
......@@ -995,7 +995,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height));
XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), 0, 0);
XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root), 0, 0);
XMapWindow(nxagentDisplay, w);
nxagentChangeOption(RootX, 0);
......@@ -1156,11 +1156,11 @@ void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift)
-nxagentOption(RootY) + nxagentOption(Height));
fprintf(stderr, "nxagentMoveViewport: Root geometry x=[%d] y=[%d]\n",
WindowTable[pScreen -> myNum] -> drawable.x,
WindowTable[pScreen -> myNum] -> drawable.y );
pScreen->root -> drawable.x,
pScreen->root -> drawable.y );
#endif
XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root),
nxagentOption(RootX), nxagentOption(RootY));
if (nxagentOption(ClientOs) == ClientOsWinnt)
......@@ -2437,7 +2437,7 @@ static int nxagentForceExposure(WindowPtr pWin, void * ptr)
{
RegionPtr exposedRgn;
BoxRec Box;
WindowPtr pRoot = WindowTable[pWin->drawable.pScreen->myNum];
WindowPtr pRoot = pWin->drawable.pScreen->root;
if (pWin -> drawable.class != InputOnly)
{
......@@ -2491,7 +2491,7 @@ void nxagentMapDefaultWindows()
for (i = 0; i < screenInfo.numScreens; i++)
{
WindowPtr pWin = WindowTable[i];
WindowPtr pWin = screenInfo.screens[i]->root;
ScreenPtr pScreen = pWin -> drawable.pScreen;
......@@ -2606,7 +2606,7 @@ Bool nxagentDisconnectAllWindows(void)
for (i = 0; i < screenInfo.numScreens; i++)
{
pWin = WindowTable[i];
pWin = screenInfo.screens[i]->root;
nxagentTraverseWindow( pWin, nxagentDisconnectWindow, &succeded);
nxagentDefaultWindows[i] = None;
}
......@@ -2684,16 +2684,16 @@ Bool nxagentReconnectAllWindows(void *p0)
fprintf(stderr, "nxagentReconnectAllWindows\n");
#endif
if (WindowTable[0] -> backgroundState == BackgroundPixmap &&
WindowTable[0] -> background.pixmap == NULL)
if (screenInfo.screens[0]->root -> backgroundState == BackgroundPixmap &&
screenInfo.screens[0]->root -> background.pixmap == NULL)
{
FatalError("nxagentReconnectAllWindows: correct the FIXME\n");
}
if (nxagentOption(Fullscreen))
{
WindowTable[0] -> origin.x = nxagentOption(RootX);
WindowTable[0] -> origin.y = nxagentOption(RootY);
screenInfo.screens[0]->root -> origin.x = nxagentOption(RootX);
screenInfo.screens[0]->root -> origin.y = nxagentOption(RootY);
}
if (!nxagentLoopOverWindows(nxagentReconnectWindow))
......@@ -2739,8 +2739,8 @@ Bool nxagentReconnectAllWindows(void *p0)
if (nxagentOption(Fullscreen))
{
WindowTable[0] -> origin.x = 0;
WindowTable[0] -> origin.y = 0;
screenInfo.screens[0]->root -> origin.x = 0;
screenInfo.screens[0]->root -> origin.y = 0;
}
#ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
......@@ -2751,7 +2751,7 @@ Bool nxagentReconnectAllWindows(void *p0)
#endif
if (nxagentInitClipboard(WindowTable[0]) == -1)
if (nxagentInitClipboard(screenInfo.screens[0]->root) == -1)
{
#ifdef WARNING
fprintf(stderr, "nxagentReconnectAllWindows: WARNING! Couldn't initialize the clipboard.\n");
......@@ -2848,7 +2848,7 @@ static Bool nxagentLoopOverWindows(void (*pF)(void *, XID, void *))
for (i = 0; i < screenInfo.numScreens; i++)
{
pWin = WindowTable[i];
pWin = screenInfo.screens[i]->root;
nxagentTraverseWindow(pWin, pF, &windowSuccess);
}
......@@ -2995,7 +2995,7 @@ FIXME: Do we need to set save unders attribute here?
* if a client handles this.
*/
if (nxagentOption(Rootless) && (pWin != WindowTable[0]))
if (nxagentOption(Rootless) && (pWin != screenInfo.screens[0]->root))
{
if (nxagentWindowTopLevel(pWin))
{
......@@ -3196,7 +3196,7 @@ static void nxagentReconfigureWindow(void * param0, XID param1, void * data_buff
nxagentShapeWindow(pWin);
#endif
if (pWin != WindowTable[0])
if (pWin != screenInfo.screens[0]->root)
{
if (pWin->realized)
{
......@@ -3238,7 +3238,7 @@ Bool nxagentCheckIllegalRootMonitoring(WindowPtr pWin, Mask mask)
Mask invalidMask = SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask;
if (nxagentOption(Rootless) &&
pWin == WindowTable[0] &&
pWin == screenInfo.screens[0]->root &&
(mask & invalidMask))
{
return True;
......
......@@ -167,7 +167,7 @@ extern int nxagentWindowPrivateIndex;
#define nxagentRefreshScreen() \
do\
{\
nxagentRefreshWindows(WindowTable[0]);\
nxagentRefreshWindows(screenInfo.screens[0]->root);\
} while (0)
WindowPtr nxagentWindowPtr(Window window);
......
......@@ -20,8 +20,8 @@ extern Bool loadableFonts;
extern int defaultColorVisualClass;
extern Bool Must_have_memory;
extern WindowPtr *WindowTable;
extern int GrabInProgress;
extern char *ConnectionInfo;
extern Bool noTestExtensions;
extern DDXPointRec dixScreenOrigins[MAXSCREENS];
......
......@@ -81,6 +81,7 @@ extern unsigned long serverGeneration;
#include <nx-X11/Xfuncproto.h>
#include <nx-X11/Xmd.h>
#include <nx-X11/X.h>
#include <stdint.h>
#ifndef _XTYPEDEF_POINTER
/* Don't let Xdefs.h define 'pointer' */
......@@ -237,6 +238,28 @@ pad_to_int32(const int bytes) {
return (((bytes) + 3) & ~3);
}
/**
* Compare the two version numbers comprising of major.minor.
*
* @return A value less than 0 if a is less than b, 0 if a is equal to b,
* or a value greater than 0
*/
static inline int
version_compare(uint32_t a_major, uint32_t a_minor,
uint32_t b_major, uint32_t b_minor)
{
if (a_major > b_major)
return 1;
if (a_major < b_major)
return -1;
if (a_minor > b_minor)
return 1;
if (a_minor < b_minor)
return -1;
return 0;
}
/* some macros to help swap requests, replies, and events */
#define LengthRestB(stuff) \
......
......@@ -523,6 +523,17 @@ typedef void (* MarkUnrealizedWindowProcPtr)(
WindowPtr /*pWin*/,
Bool /*fromConfigure*/);
typedef void (*ConstrainCursorHarderProcPtr)(
ScreenPtr, /*pScreen*/
int, /*mode*/
int *, /*x*/
int * /*y*/);
typedef Bool (*ReplaceScanoutPixmapProcPtr)(
DrawablePtr, /*pDrawable*/
PixmapPtr, /*pPixmap*/
Bool /*enable*/);
typedef struct _Screen {
int myNum; /* index of this instance in Screens[] */
ATOM id;
......@@ -549,6 +560,7 @@ typedef struct _Screen {
void * devPrivate;
short numVisuals;
VisualPtr visuals;
WindowPtr root;
int WindowPrivateLen;
unsigned *WindowPrivateSizes;
unsigned totalWindowSize;
......@@ -611,6 +623,7 @@ typedef struct _Screen {
/* Cursor Procedures */
ConstrainCursorProcPtr ConstrainCursor;
ConstrainCursorHarderProcPtr ConstrainCursorHarder;
CursorLimitsProcPtr CursorLimits;
DisplayCursorProcPtr DisplayCursor;
RealizeCursorProcPtr RealizeCursor;
......@@ -707,6 +720,7 @@ typedef struct _Screen {
ChangeBorderWidthProcPtr ChangeBorderWidth;
MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
} ScreenRec;
static inline RegionPtr BitmapToRegion(ScreenPtr _pScreen, PixmapPtr pPix) {
......
......@@ -1768,7 +1768,7 @@ miBankGetImage(
pBankImage);
(*pScreenPriv->pBankGC->ops->CopyArea)(
(DrawablePtr)WindowTable[pScreen->myNum],
(DrawablePtr)pScreen->root,
(DrawablePtr)pScreenPriv->pBankPixmap,
pScreenPriv->pBankGC,
sx + pDrawable->x, sy + pDrawable->y, w, h, 0, 0);
......@@ -1835,7 +1835,7 @@ miBankGetSpans(
continue;
(*pScreenPriv->pBankGC->ops->CopyArea)(
(DrawablePtr)WindowTable[pScreen->myNum],
(DrawablePtr)pScreen->root,
(DrawablePtr)pScreenPriv->pBankPixmap,
pScreenPriv->pBankGC,
ppt->x, ppt->y, *pwidth, 1, 0, 0);
......@@ -1958,7 +1958,7 @@ miBankCopyWindow(
ScreenPtr pScreen = pWindow->drawable.pScreen;
GCPtr pGC;
int dx, dy, nBox;
DrawablePtr pDrawable = (DrawablePtr)WindowTable[pScreen->myNum];
DrawablePtr pDrawable = (DrawablePtr)pScreen->root;
RegionPtr pRgnDst;
BoxPtr pBox, pBoxTmp, pBoxNext, pBoxBase, pBoxNew1, pBoxNew2;
XID subWindowMode = IncludeInferiors;
......
......@@ -477,7 +477,7 @@ miDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
return FALSE;
}
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pWin = WindowTable[pScreen->myNum];
pWin = pScreen->root;
#ifdef ARGB_CURSOR
if (pPriv->pPicture)
{
......@@ -523,7 +523,7 @@ miDCSaveUnderCursor (pScreen, x, y, w, h)
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pSave = pScreenPriv->pSave;
pWin = WindowTable[pScreen->myNum];
pWin = pScreen->root;
if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
{
if (pSave)
......@@ -555,7 +555,7 @@ miDCRestoreUnderCursor (pScreen, x, y, w, h)
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pSave = pScreenPriv->pSave;
pWin = WindowTable[pScreen->myNum];
pWin = pScreen->root;
if (!pSave)
return FALSE;
if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
......@@ -581,7 +581,7 @@ miDCChangeSave (pScreen, x, y, w, h, dx, dy)
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pSave = pScreenPriv->pSave;
pWin = WindowTable[pScreen->myNum];
pWin = pScreen->root;
/*
* restore the bits which are about to get trashed
*/
......@@ -723,7 +723,7 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
return FALSE;
}
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pWin = WindowTable[pScreen->myNum];
pWin = pScreen->root;
pTemp = pScreenPriv->pTemp;
if (!pTemp ||
pTemp->drawable.width != pScreenPriv->pSave->drawable.width ||
......
......@@ -468,7 +468,7 @@ miSendExposures(pWin, pRgn, dx, dy)
if(!pWin->parent) {
x = panoramiXdataPtr[scrnum].x;
y = panoramiXdataPtr[scrnum].y;
pWin = WindowTable[0];
pWin = screenInfo.screens[0]->root;
realWin = pWin->drawable.id;
} else if (scrnum) {
PanoramiXRes *win;
......@@ -715,7 +715,7 @@ int what;
gcmask |= GCFunction | GCClipMask;
i = pScreen->myNum;
pRoot = WindowTable[i];
pRoot = screenInfo.screens[i]->root;
pBgWin = pWin;
if (what == PW_BORDER)
......
......@@ -317,7 +317,7 @@ miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
{
if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
/* This could probably be more optimal */
RebuildTree(WindowTable[pWin->drawable.pScreen->myNum]->firstChild);
RebuildTree(pWin->drawable.pScreen->root->firstChild);
}
}
......@@ -1733,7 +1733,7 @@ miOverlayChangeBorderWidth(
void
miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
{
WindowPtr pRoot = WindowTable[pScreen->myNum];
WindowPtr pRoot = pScreen->root;
miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot);
MARK_UNDERLAY(pRoot);
......
......@@ -46,6 +46,7 @@ in this Software without prior written authorization from The Open Group.
# include "mipointrst.h"
# include "cursorstr.h"
# include "dixstruct.h"
# include <nx-X11/extensions/XI.h>
int miPointerScreenIndex;
static unsigned long miPointerGeneration = 0;
......@@ -224,6 +225,10 @@ miPointerSetCursorPosition(pScreen, x, y, generateEvent)
SetupScreen (pScreen);
GenerateEvent = generateEvent;
if (pScreen->ConstrainCursorHarder)
pScreen->ConstrainCursorHarder(pScreen, Absolute, &x, &y);
/* device dependent - must pend signal and call miPointerWarpCursor */
(*pScreenPriv->screenFuncs->WarpCursor) (pScreen, x, y);
if (!generateEvent)
......
......@@ -17,18 +17,61 @@
XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 keithp Exp $
#include <Server.tmpl>
SRCS = mirandr.c randr.c rrcrtc.c rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c rrproperty.c rrscreen.c rrsdispatch.c rrxinerama.c
NULL =
OBJS = mirandr.o randr.o rrcrtc.o rrdispatch.o rrinfo.o rrmode.o rroutput.o rrpointer.o rrproperty.o rrscreen.o rrsdispatch.o rrxinerama.o
SRCS = randr.c \
rrcrtc.c \
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)
OBJS = randr.o \
rrcrtc.o \
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)
INCLUDES = -I../include -I../mi \
-I../fb -I../hw/kdrive -I$(EXTINCSRC) -I$(XINCLUDESRC) \
-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()
......
/*
* Copyright © 2000 Compaq Computer Corporation
* Copyright © 2002 Hewlett-Packard Company
* Copyright © 2006 Intel Corporation
*
* 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.
*
* Author: Jim Gettys, Hewlett-Packard Company, Inc.
* Keith Packard, Intel Corporation
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "scrnintstr.h"
#include "mi.h"
#include "randrstr.h"
#include <stdio.h>
Bool
miRRGetInfo (ScreenPtr pScreen, Rotation *rotations)
{
return TRUE;
}
/*
* Any hardware that can actually change anything will need something
* different here
*/
Bool
miRRCrtcSet (ScreenPtr pScreen,
RRCrtcPtr crtc,
RRModePtr mode,
int x,
int y,
Rotation rotation,
int numOutput,
RROutputPtr *outputs)
{
return TRUE;
}
static Bool
miRRCrtcSetGamma (ScreenPtr pScreen,
RRCrtcPtr crtc)
{
return TRUE;
}
Bool
miRROutputSetProperty (ScreenPtr pScreen,
RROutputPtr output,
Atom property,
RRPropertyValuePtr value)
{
return TRUE;
}
Bool
miRROutputValidateMode (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode)
{
return FALSE;
}
void
miRRModeDestroy (ScreenPtr pScreen,
RRModePtr mode)
{
}
/*
* This function assumes that only a single depth can be
* displayed at a time, but that all visuals of that depth
* can be displayed simultaneously. It further assumes that
* only a single size is available. Hardware providing
* additional capabilties should use different code.
* XXX what to do here....
*/
Bool
miRandRInit (ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
#if RANDR_12_INTERFACE
RRModePtr mode;
RRCrtcPtr crtc;
RROutputPtr output;
xRRModeInfo modeInfo;
char name[64];
#endif
if (!RRScreenInit (pScreen))
return FALSE;
pScrPriv = rrGetScrPriv(pScreen);
pScrPriv->rrGetInfo = miRRGetInfo;
#if RANDR_12_INTERFACE
pScrPriv->rrCrtcSet = miRRCrtcSet;
pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
pScrPriv->rrOutputSetProperty = miRROutputSetProperty;
pScrPriv->rrOutputValidateMode = miRROutputValidateMode;
pScrPriv->rrModeDestroy = miRRModeDestroy;
RRScreenSetSizeRange (pScreen,
pScreen->width, pScreen->height,
pScreen->width, pScreen->height);
sprintf (name, "%dx%d", pScreen->width, pScreen->height);
memset (&modeInfo, '\0', sizeof (modeInfo));
modeInfo.width = pScreen->width;
modeInfo.height = pScreen->height;
modeInfo.nameLength = strlen (name);
mode = RRModeGet (&modeInfo, name);
if (!mode)
return FALSE;
crtc = RRCrtcCreate (pScreen, NULL);
if (!crtc)
return FALSE;
output = RROutputCreate (pScreen, "screen", 6, NULL);
if (!output)
return FALSE;
if (!RROutputSetClones (output, NULL, 0))
return FALSE;
if (!RROutputSetModes (output, &mode, 1, 0))
return FALSE;
if (!RROutputSetCrtcs (output, &crtc, 1))
return FALSE;
if (!RROutputSetConnection (output, RR_Connected))
return FALSE;
RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
#endif
return TRUE;
}
......@@ -67,13 +67,13 @@ typedef struct {
#define sz_xPanoramiXQueryVersionReply 32
typedef struct _PanoramiXGetState {
CARD8 reqType; /* always PanoramiXReqCode */
CARD8 panoramiXReqType; /* always X_PanoramiXGetState */
CARD16 length B16;
CARD32 window B32;
} xPanoramiXGetStateReq;
#define sz_xPanoramiXGetStateReq 8
typedef struct {
......@@ -97,6 +97,7 @@ typedef struct _PanoramiXGetScreenCount {
CARD16 length B16;
CARD32 window B32;
} xPanoramiXGetScreenCountReq;
#define sz_xPanoramiXGetScreenCountReq 8
typedef struct {
......@@ -111,6 +112,7 @@ typedef struct {
CARD32 pad4 B32; /* unused */
CARD32 pad5 B32; /* unused */
} xPanoramiXGetScreenCountReply;
#define sz_panoramiXGetScreenCountReply 32
typedef struct _PanoramiXGetScreenSize {
......@@ -120,6 +122,7 @@ typedef struct _PanoramiXGetScreenSize {
CARD32 window B32;
CARD32 screen B32;
} xPanoramiXGetScreenSizeReq;
#define sz_xPanoramiXGetScreenSizeReq 12
typedef struct {
......@@ -134,6 +137,7 @@ typedef struct {
CARD32 pad2 B32; /* unused */
CARD32 pad3 B32; /* unused */
} xPanoramiXGetScreenSizeReply;
#define sz_panoramiXGetScreenSizeReply 32
/************ Alternate protocol ******************/
......@@ -143,6 +147,7 @@ typedef struct {
CARD8 panoramiXReqType;
CARD16 length B16;
} xXineramaIsActiveReq;
#define sz_xXineramaIsActiveReq 4
typedef struct {
......@@ -157,14 +162,15 @@ typedef struct {
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXineramaIsActiveReply;
#define sz_XineramaIsActiveReply 32
#define sz_XineramaIsActiveReply 32
typedef struct {
CARD8 reqType;
CARD8 panoramiXReqType;
CARD16 length B16;
} xXineramaQueryScreensReq;
#define sz_xXineramaQueryScreensReq 4
typedef struct {
......@@ -179,6 +185,7 @@ typedef struct {
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXineramaQueryScreensReply;
#define sz_XineramaQueryScreensReply 32
typedef struct {
......@@ -187,6 +194,7 @@ typedef struct {
CARD16 width B16;
CARD16 height B16;
} xXineramaScreenInfo;
#define sz_XineramaScreenInfo 8
#endif
......@@ -50,6 +50,10 @@
#include "randrstr.h"
#ifndef NXAGENT_SERVER
#include "extinit.h"
#endif
/* From render.h */
#ifndef SubPixelUnknown
#define SubPixelUnknown 0
......@@ -59,16 +63,16 @@
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);
static int SProcRRDispatch (ClientPtr pClient);
static int ProcRRDispatch(ClientPtr pClient);
static int SProcRRDispatch(ClientPtr pClient);
int RREventBase;
int RRErrorBase;
......@@ -83,58 +87,60 @@ int rrPrivIndex = -1;
#endif
static void
RRClientCallback (CallbackListPtr *list,
void * closure,
void * data)
RRClientCallback(CallbackListPtr *list, void *closure, void *data)
{
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
ClientPtr pClient = clientinfo->client;
rrClientPriv(pClient);
RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
int i;
pRRClient->major_version = 0;
pRRClient->minor_version = 0;
for (i = 0; i < screenInfo.numScreens; i++)
{
for (i = 0; i < screenInfo.numScreens; i++) {
ScreenPtr pScreen = screenInfo.screens[i];
rrScrPriv(pScreen);
if (pScrPriv)
{
if (pScrPriv) {
pTimes[i].setTime = pScrPriv->lastSetTime;
pTimes[i].configTime = pScrPriv->lastConfigTime;
}
}
}
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;
unwrap (pScrPriv, pScreen, CloseScreen);
unwrap(pScrPriv, pScreen, CloseScreen);
for (j = pScrPriv->numCrtcs - 1; j >= 0; j--)
RRCrtcDestroy (pScrPriv->crtcs[j]);
RRCrtcDestroy(pScrPriv->crtcs[j]);
for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
RROutputDestroy (pScrPriv->outputs[j]);
RROutputDestroy(pScrPriv->outputs[j]);
if (pScrPriv->provider)
RRProviderDestroy(pScrPriv->provider);
RRMonitorClose(pScreen);
xfree (pScrPriv->crtcs);
xfree (pScrPriv->outputs);
xfree (pScrPriv);
xfree(pScrPriv->crtcs);
xfree(pScrPriv->outputs);
xfree(pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
return (*pScreen->CloseScreen) (i, pScreen);
}
static void
SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
xRRScreenChangeNotifyEvent *to)
SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent * from,
xRRScreenChangeNotifyEvent * to)
{
to->type = from->type;
to->rotation = from->rotation;
......@@ -144,16 +150,16 @@ 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
SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from,
xRRCrtcChangeNotifyEvent *to)
SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent * from,
xRRCrtcChangeNotifyEvent * to)
{
to->type = from->type;
to->subCode = from->subCode;
......@@ -162,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);
......@@ -171,8 +177,8 @@ SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from,
}
static void
SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from,
xRROutputChangeNotifyEvent *to)
SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent * from,
xRROutputChangeNotifyEvent * to)
{
to->type = from->type;
to->subCode = from->subCode;
......@@ -184,11 +190,13 @@ 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
SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from,
xRROutputPropertyNotifyEvent *to)
SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent * from,
xRROutputPropertyNotifyEvent * to)
{
to->type = from->type;
to->subCode = from->subCode;
......@@ -197,25 +205,81 @@ 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
SRRNotifyEvent (xEvent *from,
xEvent *to)
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
SRRNotifyEvent(xEvent *from, xEvent *to)
{
switch (from->u.u.detail) {
case RRNotify_CrtcChange:
SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from,
SRRCrtcChangeNotifyEvent((xRRCrtcChangeNotifyEvent *) from,
(xRRCrtcChangeNotifyEvent *) to);
break;
case RRNotify_OutputChange:
SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from,
SRROutputChangeNotifyEvent((xRROutputChangeNotifyEvent *) from,
(xRROutputChangeNotifyEvent *) to);
break;
case RRNotify_OutputProperty:
SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from,
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;
}
......@@ -223,33 +287,41 @@ SRRNotifyEvent (xEvent *from,
static int RRGeneration;
Bool RRInit (void)
Bool
RRInit(void)
{
if (RRGeneration != serverGeneration)
{
#ifdef NXAGENT_SERVER
if (RRGeneration != serverGeneration) {
#ifdef NXAGENT_SERVER
if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
return FALSE;
#endif
if (!RRModeInit ())
#endif
if (!RRModeInit())
return FALSE;
if (!RRCrtcInit ())
if (!RRCrtcInit())
return FALSE;
if (!RROutputInit ())
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;
}
Bool RRScreenInit(ScreenPtr pScreen)
Bool
RRScreenInit(ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
if (!RRInit ())
if (!RRInit())
return FALSE;
pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec));
pScrPriv = (rrScrPrivPtr) xcalloc(1, sizeof(rrScrPrivRec));
if (!pScrPriv)
return FALSE;
......@@ -291,20 +363,23 @@ Bool RRScreenInit(ScreenPtr pScreen)
pScrPriv->lastSetTime = currentTime;
pScrPriv->lastConfigTime = currentTime;
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
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;
}
/*ARGSUSED*/
static int
RRFreeClient (void * data, XID id)
/*ARGSUSED*/ static int
RRFreeClient(void *data, XID id)
{
RREventPtr pRREvent;
WindowPtr pWin;
......@@ -312,70 +387,84 @@ 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)
for (pCur = *pHead; pCur && pCur != pRREvent; pCur = pCur->next)
pPrev = pCur;
if (pCur)
{
if (pCur) {
if (pPrev)
pPrev->next = pRREvent->next;
else
*pHead = pRREvent->next;
}
}
xfree ((void *) pRREvent);
xfree((void *) pRREvent);
return 1;
}
/*ARGSUSED*/
static int
RRFreeEvents (void * data, XID id)
/*ARGSUSED*/ static int
RRFreeEvents(void *data, XID id)
{
RREventPtr *pHead, pCur, pNext;
pHead = (RREventPtr *) data;
for (pCur = *pHead; pCur; pCur = pNext) {
pNext = pCur->next;
FreeResource (pCur->clientResource, RRClientType);
xfree ((void *) pCur);
FreeResource(pCur->clientResource, RRClientType);
xfree((void *) pCur);
}
xfree ((void *) pHead);
xfree((void *) pHead);
return 1;
}
void
RRExtensionInit (void)
RRExtensionInit(void)
{
ExtensionEntry *extEntry;
if (RRNScreens == 0) return;
if (RRNScreens == 0)
return;
#ifndef NXAGENT_SERVER
if (!dixRequestPrivate(RRClientPrivateKey,
sizeof (RRClientRec) +
screenInfo.numScreens * sizeof (RRTimesRec)))
#ifndef NXAGENT_SERVER
if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT,
sizeof(RRClientRec) +
screenInfo.numScreens * sizeof(RRTimesRec)))
return;
#else
RRClientPrivateIndex = AllocateClientPrivateIndex ();
if (!AllocateClientPrivate (RRClientPrivateIndex,
sizeof (RRClientRec) +
screenInfo.numScreens * sizeof (RRTimesRec)))
#else /* !defined(NXAGENT_SERVER) */
RRClientPrivateIndex = AllocateClientPrivateIndex();
if (!AllocateClientPrivate(RRClientPrivateIndex,
sizeof(RRClientRec) +
screenInfo.numScreens * sizeof(RRTimesRec)))
return;
#endif
if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
#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,
extEntry = AddExtension(RANDR_NAME, RRNumberEvents, RRNumberErrors,
ProcRRDispatch, SProcRRDispatch,
RRResetProc, StandardMinorOpcode);
NULL, StandardMinorOpcode);
if (!extEntry)
return;
RRErrorBase = extEntry->errorBase;
......@@ -384,84 +473,245 @@ 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)
TellChanged(WindowPtr pWin, void *value)
{
RREventPtr *pHead, pRREvent;
ClientPtr client;
ScreenPtr pScreen = pWin->drawable.pScreen;
#ifndef NXAGENT_SERVER
ScreenPtr iter;
rrScrPrivPtr pSlaveScrPriv;
#endif
rrScrPriv(pScreen);
int i;
pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, RREventType);
#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)
{
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
client = pRREvent->client;
if (client == serverClient || client->clientGone)
continue;
if (pRREvent->mask & RRScreenChangeNotifyMask)
RRDeliverScreenEvent (client, pWin, pScreen);
RRDeliverScreenEvent(client, pWin, pScreen);
if (pRREvent->mask & RRCrtcChangeNotifyMask)
{
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
if (pRREvent->mask & RRCrtcChangeNotifyMask) {
for (i = 0; i < pScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pScrPriv->crtcs[i];
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);
RRDeliverCrtcEvent(client, pWin, crtc);
}
}
#endif
}
if (pRREvent->mask & RROutputChangeNotifyMask)
{
for (i = 0; i < pScrPriv->numOutputs; i++)
{
if (pRREvent->mask & RROutputChangeNotifyMask) {
for (i = 0; i < pScrPriv->numOutputs; i++) {
RROutputPtr output = pScrPriv->outputs[i];
if (output->changed)
RRDeliverOutputEvent (client, pWin, output);
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)
RRTellChanged(ScreenPtr pScreen)
{
rrScrPriv (pScreen);
ScreenPtr master;
rrScrPriv(pScreen);
rrScrPrivPtr mastersp;
int i;
#ifndef NXAGENT_SERVER
ScreenPtr iter;
rrScrPrivPtr pSlaveScrPriv;
#endif
if (pScrPriv->changed)
{
UpdateCurrentTime ();
if (pScrPriv->configChanged)
#ifndef NXAGENT_SERVER
if (pScreen->isGPU) {
master = pScreen->current_master;
mastersp = rrGetScrPriv(master);
}
else
#endif
{
pScrPriv->lastConfigTime = currentTime;
pScrPriv->configChanged = FALSE;
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);
}
}
}
......@@ -471,17 +721,22 @@ RRTellChanged (ScreenPtr pScreen)
* Used in emulating 1.0 behaviour
*/
RROutputPtr
RRFirstOutput (ScreenPtr pScreen)
RRFirstOutput(ScreenPtr pScreen)
{
rrScrPriv(pScreen);
RROutputPtr output;
int i, j;
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
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];
for (j = 0; j < pScrPriv->numOutputs; j++)
{
for (j = 0; j < pScrPriv->numOutputs; j++) {
output = pScrPriv->outputs[j];
if (output->crtc == crtc)
return output;
......@@ -491,33 +746,35 @@ RRFirstOutput (ScreenPtr pScreen)
}
CARD16
RRVerticalRefresh (xRRModeInfo *mode)
RRVerticalRefresh(xRRModeInfo * mode)
{
CARD32 refresh;
CARD32 dots = mode->hTotal * mode->vTotal;
if (!dots)
return 0;
refresh = (mode->dotClock + dots/2) / dots;
refresh = (mode->dotClock + dots / 2) / dots;
if (refresh > 0xffff)
refresh = 0xffff;
return (CARD16) refresh;
}
static int
ProcRRDispatch (ClientPtr client)
ProcRRDispatch(ClientPtr client)
{
REQUEST(xReq);
if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
return BadRequest;
UpdateCurrentTimeIf();
return (*ProcRandrVector[stuff->data]) (client);
}
static int
SProcRRDispatch (ClientPtr client)
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);
}
......@@ -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_ */
......@@ -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
......@@ -63,6 +66,7 @@ typedef struct {
CARD16 widthInMillimeters B16;
CARD16 heightInMillimeters B16;
} xScreenSizes;
#define sz_xScreenSizes 8
/*
......@@ -76,6 +80,7 @@ typedef struct {
CARD32 majorVersion B32;
CARD32 minorVersion B32;
} xRRQueryVersionReq;
#define sz_xRRQueryVersionReq 12
typedef struct {
......@@ -90,6 +95,7 @@ typedef struct {
CARD32 pad4 B32;
CARD32 pad5 B32;
} xRRQueryVersionReply;
#define sz_xRRQueryVersionReply 32
typedef struct {
......@@ -98,6 +104,7 @@ typedef struct {
CARD16 length B16;
Window window B32;
} xRRGetScreenInfoReq;
#define sz_xRRGetScreenInfoReq 8
/*
......@@ -106,7 +113,6 @@ typedef struct {
* the size information
*/
typedef struct {
BYTE type; /* X_Reply */
BYTE setOfRotations;
......@@ -122,6 +128,7 @@ typedef struct {
CARD16 nrateEnts B16;
CARD16 pad B16;
} xRRGetScreenInfoReply;
#define sz_xRRGetScreenInfoReply 32
typedef struct {
......@@ -134,6 +141,7 @@ typedef struct {
SizeID sizeID B16;
Rotation rotation B16;
} xRR1_0SetScreenConfigReq;
#define sz_xRR1_0SetScreenConfigReq 20
typedef struct {
......@@ -148,6 +156,7 @@ typedef struct {
CARD16 rate B16;
CARD16 pad B16;
} xRRSetScreenConfigReq;
#define sz_xRRSetScreenConfigReq 24
typedef struct {
......@@ -163,6 +172,7 @@ typedef struct {
CARD32 pad5 B32;
CARD32 pad6 B32;
} xRRSetScreenConfigReply;
#define sz_xRRSetScreenConfigReply 32
typedef struct {
......@@ -173,6 +183,7 @@ typedef struct {
CARD16 enable B16;
CARD16 pad2 B16;
} xRRSelectInputReq;
#define sz_xRRSelectInputReq 12
/*
......@@ -194,6 +205,7 @@ typedef struct _xRRModeInfo {
CARD16 nameLength B16;
RRModeFlags modeFlags B32;
} xRRModeInfo;
#define sz_xRRModeInfo 32
typedef struct {
......@@ -202,6 +214,7 @@ typedef struct {
CARD16 length B16;
Window window B32;
} xRRGetScreenSizeRangeReq;
#define sz_xRRGetScreenSizeRangeReq 8
typedef struct {
......@@ -218,6 +231,7 @@ typedef struct {
CARD32 pad2 B32;
CARD32 pad3 B32;
} xRRGetScreenSizeRangeReply;
#define sz_xRRGetScreenSizeRangeReply 32
typedef struct {
......@@ -230,6 +244,7 @@ typedef struct {
CARD32 widthInMillimeters B32;
CARD32 heightInMillimeters B32;
} xRRSetScreenSizeReq;
#define sz_xRRSetScreenSizeReq 20
typedef struct {
......@@ -238,6 +253,7 @@ typedef struct {
CARD16 length B16;
Window window B32;
} xRRGetScreenResourcesReq;
#define sz_xRRGetScreenResourcesReq 8
typedef struct {
......@@ -254,6 +270,7 @@ typedef struct {
CARD32 pad1 B32;
CARD32 pad2 B32;
} xRRGetScreenResourcesReply;
#define sz_xRRGetScreenResourcesReply 32
typedef struct {
......@@ -263,6 +280,7 @@ typedef struct {
RROutput output B32;
Time configTimestamp B32;
} xRRGetOutputInfoReq;
#define sz_xRRGetOutputInfoReq 12
typedef struct {
......@@ -282,6 +300,7 @@ typedef struct {
CARD16 nClones B16;
CARD16 nameLength B16;
} xRRGetOutputInfoReply;
#define sz_xRRGetOutputInfoReply 36
typedef struct {
......@@ -290,6 +309,7 @@ typedef struct {
CARD16 length B16;
RROutput output B32;
} xRRListOutputPropertiesReq;
#define sz_xRRListOutputPropertiesReq 8
typedef struct {
......@@ -305,6 +325,7 @@ typedef struct {
CARD32 pad5 B32;
CARD32 pad6 B32;
} xRRListOutputPropertiesReply;
#define sz_xRRListOutputPropertiesReply 32
typedef struct {
......@@ -314,6 +335,7 @@ typedef struct {
RROutput output B32;
Atom property B32;
} xRRQueryOutputPropertyReq;
#define sz_xRRQueryOutputPropertyReq 12
typedef struct {
......@@ -331,6 +353,7 @@ typedef struct {
CARD32 pad5 B32;
CARD32 pad6 B32;
} xRRQueryOutputPropertyReply;
#define sz_xRRQueryOutputPropertyReply 32
typedef struct {
......@@ -343,6 +366,7 @@ typedef struct {
BOOL range;
CARD16 pad B16;
} xRRConfigureOutputPropertyReq;
#define sz_xRRConfigureOutputPropertyReq 16
typedef struct {
......@@ -357,6 +381,7 @@ typedef struct {
CARD16 pad;
CARD32 nUnits B32;
} xRRChangeOutputPropertyReq;
#define sz_xRRChangeOutputPropertyReq 24
typedef struct {
......@@ -366,6 +391,7 @@ typedef struct {
RROutput output B32;
Atom property B32;
} xRRDeleteOutputPropertyReq;
#define sz_xRRDeleteOutputPropertyReq 12
typedef struct {
......@@ -385,6 +411,7 @@ typedef struct {
BOOL pending;
CARD16 pad1 B16;
} xRRGetOutputPropertyReq;
#define sz_xRRGetOutputPropertyReq 28
typedef struct {
......@@ -399,6 +426,7 @@ typedef struct {
CARD32 pad2 B32;
CARD32 pad3 B32;
} xRRGetOutputPropertyReply;
#define sz_xRRGetOutputPropertyReply 32
typedef struct {
......@@ -408,6 +436,7 @@ typedef struct {
Window window B32;
xRRModeInfo modeInfo;
} xRRCreateModeReq;
#define sz_xRRCreateModeReq 40
typedef struct {
......@@ -422,6 +451,7 @@ typedef struct {
CARD32 pad4 B32;
CARD32 pad5 B32;
} xRRCreateModeReply;
#define sz_xRRCreateModeReply 32
typedef struct {
......@@ -430,6 +460,7 @@ typedef struct {
CARD16 length B16;
RRMode mode B32;
} xRRDestroyModeReq;
#define sz_xRRDestroyModeReq 8
typedef struct {
......@@ -439,6 +470,7 @@ typedef struct {
RROutput output B32;
RRMode mode B32;
} xRRAddOutputModeReq;
#define sz_xRRAddOutputModeReq 12
typedef struct {
......@@ -448,6 +480,7 @@ typedef struct {
RROutput output B32;
RRMode mode B32;
} xRRDeleteOutputModeReq;
#define sz_xRRDeleteOutputModeReq 12
typedef struct {
......@@ -457,6 +490,7 @@ typedef struct {
RRCrtc crtc B32;
Time configTimestamp B32;
} xRRGetCrtcInfoReq;
#define sz_xRRGetCrtcInfoReq 12
typedef struct {
......@@ -475,6 +509,7 @@ typedef struct {
CARD16 nOutput B16;
CARD16 nPossibleOutput B16;
} xRRGetCrtcInfoReply;
#define sz_xRRGetCrtcInfoReply 32
typedef struct {
......@@ -490,6 +525,7 @@ typedef struct {
Rotation rotation B16;
CARD16 pad B16;
} xRRSetCrtcConfigReq;
#define sz_xRRSetCrtcConfigReq 28
typedef struct {
......@@ -504,6 +540,7 @@ typedef struct {
CARD32 pad4 B32;
CARD32 pad5 B32;
} xRRSetCrtcConfigReply;
#define sz_xRRSetCrtcConfigReply 32
typedef struct {
......@@ -512,6 +549,7 @@ typedef struct {
CARD16 length B16;
RRCrtc crtc B32;
} xRRGetCrtcGammaSizeReq;
#define sz_xRRGetCrtcGammaSizeReq 8
typedef struct {
......@@ -527,6 +565,7 @@ typedef struct {
CARD32 pad5 B32;
CARD32 pad6 B32;
} xRRGetCrtcGammaSizeReply;
#define sz_xRRGetCrtcGammaSizeReply 32
typedef struct {
......@@ -535,6 +574,7 @@ typedef struct {
CARD16 length B16;
RRCrtc crtc B32;
} xRRGetCrtcGammaReq;
#define sz_xRRGetCrtcGammaReq 8
typedef struct {
......@@ -550,6 +590,7 @@ typedef struct {
CARD32 pad5 B32;
CARD32 pad6 B32;
} xRRGetCrtcGammaReply;
#define sz_xRRGetCrtcGammaReply 32
typedef struct {
......@@ -560,9 +601,300 @@ typedef struct {
CARD16 size B16;
CARD16 pad1 B16;
} xRRSetCrtcGammaReq;
#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 {
......@@ -580,6 +912,7 @@ typedef struct {
CARD16 widthInMillimeters B16;
CARD16 heightInMillimeters B16;
} xRRScreenChangeNotifyEvent;
#define sz_xRRScreenChangeNotifyEvent 32
typedef struct {
......@@ -597,14 +930,15 @@ typedef struct {
CARD16 width B16; /* new size */
CARD16 height B16;
} xRRCrtcChangeNotifyEvent;
#define sz_xRRCrtcChangeNotifyEvent 32
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 */
......@@ -613,6 +947,7 @@ typedef struct {
CARD8 connection; /* connection status */
CARD8 subpixelOrder; /* subpixel order */
} xRROutputChangeNotifyEvent;
#define sz_xRROutputChangeNotifyEvent 32
typedef struct {
......@@ -629,14 +964,193 @@ typedef struct {
CARD32 pad3 B32;
CARD32 pad4 B32;
} xRROutputPropertyNotifyEvent;
#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
......@@ -651,5 +1165,6 @@ typedef struct {
#undef Rotation
#undef SizeID
#undef SubpixelOrder
#undef Atom
#endif /* _XRANDRP_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,31 +48,31 @@
#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;
extern int (*ProcRandrVector[RRNumberRequests])(ClientPtr);
extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr);
extern int (*ProcRandrVector[RRNumberRequests]) (ClientPtr);
extern int (*SProcRandrVector[RRNumberRequests]) (ClientPtr);
/*
* Modeline for a monitor. Name follows directly after this struct
......@@ -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,12 +162,40 @@ 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,
CARD16 height,
CARD32 mmWidth,
CARD32 mmHeight);
CARD32 mmWidth, CARD32 mmHeight);
typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
RRCrtcPtr crtc,
......@@ -160,11 +203,11 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
int x,
int y,
Rotation rotation,
int numOutputs,
RROutputPtr *outputs);
int numOutputs, RROutputPtr * outputs);
typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen,
RRCrtcPtr crtc);
typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
RROutputPtr output,
......@@ -175,13 +218,45 @@ typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode);
typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen,
RRModePtr mode);
typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, RRModePtr mode);
#endif
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen);
#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) (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,11 +277,11 @@ typedef struct _rrScreenSize {
typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize);
int rate, RRScreenSizePtr pSize);
#endif
typedef Bool (*RRCrtcSetScanoutPixmapProcPtr) (RRCrtcPtr crtc, PixmapPtr pixmap);
typedef struct _rrScrPriv {
/*
......@@ -221,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
......@@ -236,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;
......@@ -244,6 +333,7 @@ typedef struct _rrScrPriv {
int numOutputs;
RROutputPtr *outputs;
RROutputPtr primaryOutput;
int numCrtcs;
RRCrtcPtr *crtcs;
......@@ -265,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;
......@@ -279,13 +381,13 @@ extern int rrPrivIndex;
#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 SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (void *) (p))
#endif
#endif /* !defined(NXAGENT_SERVER) */
/*
* each window has a list of clients requesting
......@@ -317,12 +419,16 @@ typedef struct _RRClient {
} RRClientRec, *RRClientPtr;
extern RESTYPE RRClientType, RREventType; /* resource types for event masks */
#ifndef NXAGENT_SERVER
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, \
......@@ -333,37 +439,122 @@ extern RESTYPE RRCrtcType, RRModeType, RROutputType;
#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)
#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);
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
RRScreenSetSizeRange (ScreenPtr pScreen,
extern _X_EXPORT void
RRScreenSetSizeRange(ScreenPtr pScreen,
CARD16 minWidth,
CARD16 minHeight,
CARD16 maxWidth,
CARD16 maxHeight);
CARD16 minHeight, CARD16 maxWidth, CARD16 maxHeight);
#endif
/* rrscreen.c */
......@@ -372,109 +563,78 @@ RRScreenSetSizeRange (ScreenPtr pScreen,
* The driver is responsible for calling this whenever it has changed
* the size of the screen
*/
void
RRScreenSizeNotify (ScreenPtr pScreen);
extern _X_EXPORT void
RRScreenSizeNotify(ScreenPtr pScreen);
/*
* Request that the screen be resized
*/
Bool
RRScreenSizeSet (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
CARD32 mmWidth,
CARD32 mmHeight);
extern _X_EXPORT Bool
RRScreenSizeSet(ScreenPtr pScreen,
CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight);
/*
* Send ConfigureNotify event to root window when 'something' happens
*/
void
RRSendConfigNotify (ScreenPtr pScreen);
extern _X_EXPORT void
RRSendConfigNotify(ScreenPtr pScreen);
/*
* screen dispatch
*/
int
ProcRRGetScreenSizeRange (ClientPtr client);
extern _X_EXPORT int
ProcRRGetScreenSizeRange(ClientPtr client);
int
ProcRRSetScreenSize (ClientPtr client);
extern _X_EXPORT int
ProcRRSetScreenSize(ClientPtr client);
int
ProcRRGetScreenResources (ClientPtr client);
extern _X_EXPORT int
ProcRRGetScreenResources(ClientPtr client);
int
ProcRRSetScreenConfig (ClientPtr client);
extern _X_EXPORT int
ProcRRGetScreenResourcesCurrent(ClientPtr client);
int
ProcRRGetScreenInfo (ClientPtr client);
extern _X_EXPORT int
ProcRRSetScreenConfig(ClientPtr client);
extern _X_EXPORT int
ProcRRGetScreenInfo(ClientPtr client);
/*
* Deliver a ScreenNotify event
*/
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);
extern _X_EXPORT void
RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen);
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
RRTellChanged (ScreenPtr pScreen);
extern _X_EXPORT void
RRTellChanged(ScreenPtr pScreen);
/*
* Poll the driver for changed information
*/
Bool
RRGetInfo (ScreenPtr pScreen);
Bool RRInit (void);
extern _X_EXPORT Bool
RRGetInfo(ScreenPtr pScreen, Bool force_query);
Bool RRScreenInit(ScreenPtr pScreen);
extern _X_EXPORT Bool RRInit(void);
RROutputPtr
RRFirstOutput (ScreenPtr pScreen);
extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen);
Rotation
RRGetRotation (ScreenPtr pScreen);
extern _X_EXPORT RROutputPtr RRFirstOutput(ScreenPtr pScreen);
CARD16
RRVerticalRefresh (xRRModeInfo *mode);
extern _X_EXPORT CARD16
RRVerticalRefresh(xRRModeInfo * mode);
#ifdef RANDR_10_INTERFACE
/*
......@@ -486,37 +646,24 @@ RRVerticalRefresh (xRRModeInfo *mode);
* Then, register the specific size with the screen
*/
RRScreenSizePtr
RRRegisterSize (ScreenPtr pScreen,
short width,
short height,
short mmWidth,
short mmHeight);
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
RRSetCurrentConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize);
extern _X_EXPORT void
Bool RRScreenInit (ScreenPtr pScreen);
Rotation
RRGetRotation (ScreenPtr pScreen);
RRSetCurrentConfig(ScreenPtr pScreen,
Rotation rotation, int rate, RRScreenSizePtr pSize);
int
RRSetScreenConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize);
extern _X_EXPORT Rotation RRGetRotation(ScreenPtr pScreen);
#endif
......@@ -526,58 +673,66 @@ RRSetScreenConfig (ScreenPtr pScreen,
* Notify the CRTC of some change; layoutChanged indicates that
* some position or size element changed
*/
void
RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
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
RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
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
RRCrtcNotify (RRCrtcPtr crtc,
extern _X_EXPORT Bool
RRCrtcNotify(RRCrtcPtr crtc,
RRModePtr mode,
int x,
int y,
Rotation rotation,
int numOutputs,
RROutputPtr *outputs);
RRTransformPtr transform, int numOutputs, RROutputPtr * outputs);
void
RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
extern _X_EXPORT void
RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
/*
* Request that the Crtc be reconfigured
*/
Bool
RRCrtcSet (RRCrtcPtr crtc,
extern _X_EXPORT Bool
RRCrtcSet(RRCrtcPtr crtc,
RRModePtr mode,
int x,
int y,
Rotation rotation,
int numOutput,
RROutputPtr *outputs);
int y, Rotation rotation, int numOutput, RROutputPtr * outputs);
/*
* Request that the Crtc gamma be changed
*/
Bool
RRCrtcGammaSet (RRCrtcPtr crtc,
CARD16 *red,
CARD16 *green,
CARD16 *blue);
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
......@@ -585,102 +740,158 @@ RRCrtcGammaSet (RRCrtcPtr crtc,
* in the RRCrtcRec
*/
Bool
RRCrtcGammaNotify (RRCrtcPtr crtc);
extern _X_EXPORT Bool
RRCrtcGammaNotify(RRCrtcPtr crtc);
/*
* Set the size of the gamma table at server startup time
*/
Bool
RRCrtcGammaSetSize (RRCrtcPtr crtc,
int size);
extern _X_EXPORT Bool
RRCrtcGammaSetSize(RRCrtcPtr crtc, int size);
/*
* Return the area of the frame buffer scanned out by the crtc,
* taking into account the current mode and rotation
*/
void
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
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
RRCrtcDestroy (RRCrtcPtr crtc);
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
RRCrtcInit (void);
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
ProcRRGetCrtcInfo (ClientPtr client);
extern _X_EXPORT int
ProcRRGetCrtcInfo(ClientPtr client);
int
ProcRRSetCrtcConfig (ClientPtr client);
extern _X_EXPORT int
ProcRRSetCrtcConfig(ClientPtr client);
int
ProcRRGetCrtcGammaSize (ClientPtr client);
extern _X_EXPORT int
ProcRRGetCrtcGammaSize(ClientPtr client);
extern _X_EXPORT int
ProcRRGetCrtcGamma(ClientPtr client);
extern _X_EXPORT int
ProcRRSetCrtcGamma(ClientPtr client);
extern _X_EXPORT int
ProcRRSetCrtcTransform(ClientPtr client);
extern _X_EXPORT int
ProcRRGetCrtcTransform(ClientPtr client);
int
ProcRRGetCrtcGamma (ClientPtr client);
ProcRRGetPanning(ClientPtr client);
int
ProcRRSetCrtcGamma (ClientPtr client);
ProcRRSetPanning(ClientPtr client);
void
RRConstrainCursorHarder(
#ifndef NXAGENT_SERVER
DeviceIntPtr,
#endif /* !defined(NXAGENT_SERVER) */
ScreenPtr, int, int *, int *);
/* rrdispatch.c */
Bool
RRClientKnowsRates (ClientPtr pClient);
extern _X_EXPORT Bool
RRClientKnowsRates(ClientPtr pClient);
/* rrmode.c */
/*
* 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
RRModeDestroy (RRModePtr mode);
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
RRModeInit (void);
extern _X_EXPORT Bool
RRModeInit(void);
int
ProcRRCreateMode (ClientPtr client);
/*
* Initialize mode type error value
*/
extern _X_EXPORT void
RRModeInitErrorValue(void);
int
ProcRRDestroyMode (ClientPtr client);
extern _X_EXPORT int
ProcRRCreateMode(ClientPtr client);
int
ProcRRAddOutputMode (ClientPtr client);
extern _X_EXPORT int
ProcRRDestroyMode(ClientPtr client);
int
ProcRRDeleteOutputMode (ClientPtr client);
extern _X_EXPORT int
ProcRRAddOutputMode(ClientPtr client);
extern _X_EXPORT int
ProcRRDeleteOutputMode(ClientPtr client);
/* rroutput.c */
......@@ -690,128 +901,245 @@ ProcRRDeleteOutputMode (ClientPtr client);
* has changed, or whether the change was strictly internal
* (which crtc is in use)
*/
void
RROutputChanged (RROutputPtr output, Bool configChanged);
extern _X_EXPORT void
RROutputChanged(RROutputPtr output, Bool configChanged);
/*
* Create an output
*/
RROutputPtr
RROutputCreate (ScreenPtr pScreen,
const char *name,
int nameLength,
void *devPrivate);
extern _X_EXPORT RROutputPtr
RROutputCreate(ScreenPtr pScreen,
const char *name, int nameLength, void *devPrivate);
/*
* Notify extension that output parameters have been changed
*/
Bool
RROutputSetClones (RROutputPtr output,
RROutputPtr *clones,
int numClones);
extern _X_EXPORT Bool
RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones);
Bool
RROutputSetModes (RROutputPtr output,
RRModePtr *modes,
int numModes,
int numPreferred);
extern _X_EXPORT Bool
int
RROutputAddUserMode (RROutputPtr output,
RRModePtr mode);
RROutputSetModes(RROutputPtr output,
RRModePtr * modes, int numModes, int numPreferred);
int
RROutputDeleteUserMode (RROutputPtr output,
RRModePtr mode);
extern _X_EXPORT int
RROutputAddUserMode(RROutputPtr output, RRModePtr mode);
Bool
RROutputSetCrtcs (RROutputPtr output,
RRCrtcPtr *crtcs,
int numCrtcs);
extern _X_EXPORT int
RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode);
Bool
RROutputSetConnection (RROutputPtr output,
CARD8 connection);
extern _X_EXPORT Bool
RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs);
Bool
RROutputSetSubpixelOrder (RROutputPtr output,
int subpixelOrder);
extern _X_EXPORT Bool
RROutputSetConnection(RROutputPtr output, CARD8 connection);
Bool
RROutputSetPhysicalSize (RROutputPtr output,
int mmWidth,
int mmHeight);
extern _X_EXPORT Bool
RROutputSetSubpixelOrder(RROutputPtr output, int subpixelOrder);
void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
extern _X_EXPORT Bool
RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight);
void
RROutputDestroy (RROutputPtr output);
extern _X_EXPORT void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
int
ProcRRGetOutputInfo (ClientPtr client);
extern _X_EXPORT void
RROutputDestroy(RROutputPtr output);
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
RROutputInit (void);
extern _X_EXPORT Bool
RROutputInit(void);
/*
* Initialize output type error value
*/
extern _X_EXPORT void
RROutputInitErrorValue(void);
/* rrpointer.c */
void
RRPointerMoved (ScreenPtr pScreen, int x, int y);
extern _X_EXPORT void
RRPointerMoved(ScreenPtr pScreen, int x, int y);
void
RRPointerScreenConfigured (ScreenPtr pScreen);
extern _X_EXPORT void
RRPointerScreenConfigured(ScreenPtr pScreen);
/* rrproperty.c */
void
RRDeleteAllOutputProperties (RROutputPtr output);
extern _X_EXPORT void
RRDeleteAllOutputProperties(RROutputPtr output);
RRPropertyValuePtr
RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending);
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
RRDeleteOutputProperty (RROutputPtr output, Atom property);
extern _X_EXPORT void
RRDeleteOutputProperty(RROutputPtr output, Atom property);
Bool
RRPostPendingProperties (RROutputPtr output);
extern _X_EXPORT Bool
RRPostPendingProperties(RROutputPtr output);
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
extern _X_EXPORT int
RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
void * value, Bool sendevent, Bool pending);
void *value, Bool sendevent, Bool pending);
int
RRConfigureOutputProperty (RROutputPtr output, Atom property,
extern _X_EXPORT int
RRConfigureOutputProperty(RROutputPtr output, Atom property,
Bool pending, Bool range, Bool immutable,
int num_values, INT32 *values);
int
ProcRRChangeOutputProperty (ClientPtr client);
extern _X_EXPORT int
ProcRRChangeOutputProperty(ClientPtr client);
int
ProcRRGetOutputProperty (ClientPtr client);
extern _X_EXPORT int
ProcRRGetOutputProperty(ClientPtr client);
extern _X_EXPORT int
ProcRRListOutputProperties(ClientPtr client);
extern _X_EXPORT int
ProcRRQueryOutputProperty(ClientPtr client);
extern _X_EXPORT int
ProcRRConfigureOutputProperty(ClientPtr client);
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 */
#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
ProcRRListOutputProperties (ClientPtr client);
RRMonitorCountList(ScreenPtr screen);
void
RRMonitorFreeList(RRMonitorPtr monitors, int nmon);
void
RRMonitorClose(ScreenPtr screen);
RRMonitorPtr
RRMonitorAlloc(int noutput);
int
ProcRRQueryOutputProperty (ClientPtr client);
RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor);
void
RRMonitorFree(RRMonitorPtr monitor);
int
ProcRRConfigureOutputProperty (ClientPtr client);
ProcRRGetMonitors(ClientPtr client);
int
ProcRRDeleteOutputProperty (ClientPtr client);
ProcRRSetMonitor(ClientPtr client);
/* rrxinerama.c */
void
RRXineramaExtensionInit(void);
int
ProcRRDeleteMonitor(ClientPtr client);
#endif /* _RANDRSTR_H_ */
......
......@@ -29,7 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* not be a stack variable.
*/
void RegisterResourceName(RESTYPE type, char *name);
void RegisterExtensionNames(ExtensionEntry *ext);
void RegisterExtensionNames(ExtensionEntry * ext);
/*
* Lookup functions. The returned string must not be modified or freed.
......
/*
* 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;
......@@ -47,16 +48,15 @@ RESTYPE RRCrtcType;
* Notify the CRTC of some change
*/
void
RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged)
{
ScreenPtr pScreen = crtc->pScreen;
crtc->changed = TRUE;
if (pScreen)
{
if (pScreen) {
rrScrPriv(pScreen);
pScrPriv->changed = TRUE;
RRSetChanged(pScreen);
/*
* Send ConfigureNotify on any layout change
*/
......@@ -69,7 +69,7 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
* Create a CRTC
*/
RRCrtcPtr
RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
{
RRCrtcPtr crtc;
RRCrtcPtr *crtcs;
......@@ -82,18 +82,23 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
/* make space for the crtc pointer */
if (pScrPriv->numCrtcs)
crtcs = xrealloc (pScrPriv->crtcs,
(pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
#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));
crtcs = xalloc(sizeof(RRCrtcPtr));
if (!crtcs)
return FALSE;
pScrPriv->crtcs = crtcs;
crtc = xcalloc (1, sizeof (RRCrtcRec));
crtc = xcalloc(1, sizeof(RRCrtcRec));
if (!crtc)
return NULL;
crtc->id = FakeClientID (0);
crtc->id = FakeClientID(0);
crtc->pScreen = pScreen;
crtc->mode = NULL;
crtc->x = 0;
......@@ -106,14 +111,21 @@ 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))
if (!AddResource(crtc->id, RRCrtcType, (void *) crtc))
return NULL;
/* attach the screen and crtc together */
crtc->pScreen = pScreen;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
RRResourcesChanged(pScreen);
return crtc;
}
......@@ -121,23 +133,31 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
* Set the allowed rotations on a CRTC
*/
void
RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations)
{
crtc->rotations = 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
*/
Bool
RRCrtcNotify (RRCrtcPtr crtc,
RRCrtcNotify(RRCrtcPtr crtc,
RRModePtr mode,
int x,
int y,
Rotation rotation,
int numOutputs,
RROutputPtr *outputs)
RRTransformPtr transform, int numOutputs, RROutputPtr * outputs)
{
int i, j;
......@@ -145,56 +165,57 @@ RRCrtcNotify (RRCrtcPtr crtc,
* Check to see if any of the new outputs were
* not in the old list and mark them as changed
*/
for (i = 0; i < numOutputs; i++)
{
for (i = 0; i < numOutputs; i++) {
for (j = 0; j < crtc->numOutputs; j++)
if (outputs[i] == crtc->outputs[j])
break;
if (j == crtc->numOutputs)
{
if (j == crtc->numOutputs) {
outputs[i]->crtc = crtc;
RROutputChanged (outputs[i], FALSE);
RRCrtcChanged (crtc, FALSE);
RROutputChanged(outputs[i], FALSE);
RRCrtcChanged(crtc, FALSE);
}
}
/*
* Check to see if any of the old outputs are
* not in the new list and mark them as changed
*/
for (j = 0; j < crtc->numOutputs; j++)
{
for (j = 0; j < crtc->numOutputs; j++) {
for (i = 0; i < numOutputs; i++)
if (outputs[i] == crtc->outputs[j])
break;
if (i == numOutputs)
{
if (i == numOutputs) {
if (crtc->outputs[j]->crtc == crtc)
crtc->outputs[j]->crtc = NULL;
RROutputChanged (crtc->outputs[j], FALSE);
RRCrtcChanged (crtc, FALSE);
RROutputChanged(crtc->outputs[j], FALSE);
RRCrtcChanged(crtc, FALSE);
}
}
/*
* Reallocate the crtc output array if necessary
*/
if (numOutputs != crtc->numOutputs)
{
if (numOutputs != crtc->numOutputs) {
RROutputPtr *newoutputs;
if (numOutputs)
{
if (numOutputs) {
if (crtc->numOutputs)
newoutputs = xrealloc (crtc->outputs,
numOutputs * sizeof (RROutputPtr));
#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
newoutputs = xalloc (numOutputs * sizeof (RROutputPtr));
#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);
else {
xfree(crtc->outputs);
newoutputs = NULL;
}
crtc->outputs = newoutputs;
......@@ -203,119 +224,444 @@ RRCrtcNotify (RRCrtcPtr crtc,
/*
* Copy the new list of outputs into the crtc
*/
memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr));
memcpy(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr));
/*
* Update remaining crtc fields
*/
if (mode != crtc->mode)
{
if (mode != crtc->mode) {
if (crtc->mode)
RRModeDestroy (crtc->mode);
RRModeDestroy(crtc->mode);
crtc->mode = mode;
if (mode != NULL)
mode->refcnt++;
RRCrtcChanged (crtc, TRUE);
RRCrtcChanged(crtc, TRUE);
}
if (x != crtc->x)
{
if (x != crtc->x) {
crtc->x = x;
RRCrtcChanged (crtc, TRUE);
RRCrtcChanged(crtc, TRUE);
}
if (y != crtc->y)
{
if (y != crtc->y) {
crtc->y = y;
RRCrtcChanged (crtc, TRUE);
RRCrtcChanged(crtc, TRUE);
}
if (rotation != crtc->rotation)
{
if (rotation != crtc->rotation) {
crtc->rotation = rotation;
RRCrtcChanged (crtc, TRUE);
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;
}
void
RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
xRRCrtcChangeNotifyEvent ce;
rrScrPriv(pScreen);
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;
}
WriteEventsToClient (client, 1, (xEvent *) &ce);
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);
}
static Bool
RRCrtcPendingProperties (RRCrtcPtr crtc)
RRCrtcPendingProperties(RRCrtcPtr crtc)
{
ScreenPtr pScreen = crtc->pScreen;
rrScrPriv(pScreen);
int o;
for (o = 0; o < pScrPriv->numOutputs; o++)
{
for (o = 0; o < pScrPriv->numOutputs; o++) {
RROutputPtr output = pScrPriv->outputs[o];
if (output->crtc == crtc && output->pendingProperties)
return TRUE;
}
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
*/
Bool
RRCrtcSet (RRCrtcPtr crtc,
RRCrtcSet(RRCrtcPtr crtc,
RRModePtr mode,
int x,
int y,
Rotation rotation,
int numOutputs,
RROutputPtr *outputs)
int y, Rotation rotation, int numOutputs, RROutputPtr * outputs)
{
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 &&
crtc->y == y &&
crtc->rotation == rotation &&
crtc->numOutputs == numOutputs &&
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
!RRCrtcPendingProperties (crtc))
{
!memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr)) &&
!RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc) &&
!crtcChanged) {
recompute = FALSE;
ret = TRUE;
}
else
{
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)
{
if (pScrPriv->rrCrtcSet) {
ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
rotation, numOutputs, outputs);
}
......@@ -323,94 +669,119 @@ RRCrtcSet (RRCrtcPtr crtc,
#endif
{
#if RANDR_10_INTERFACE
if (pScrPriv->rrSetConfig)
{
if (pScrPriv->rrSetConfig) {
RRScreenSize size;
RRScreenRate rate;
if (!mode)
{
RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
if (!mode) {
RRCrtcNotify(crtc, NULL, x, y, rotation, NULL, 0, NULL);
ret = TRUE;
}
else
{
else {
size.width = mode->mode.width;
size.height = mode->mode.height;
if (outputs[0]->mmWidth && outputs[0]->mmHeight)
{
if (outputs[0]->mmWidth && outputs[0]->mmHeight) {
size.mmWidth = outputs[0]->mmWidth;
size.mmHeight = outputs[0]->mmHeight;
}
else
{
else {
size.mmWidth = pScreen->mmWidth;
size.mmHeight = pScreen->mmHeight;
}
size.nRates = 1;
rate.rate = RRVerticalRefresh (&mode->mode);
rate.rate = RRVerticalRefresh(&mode->mode);
size.pRates = &rate;
ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
ret =
(*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate,
&size);
/*
* Old 1.0 interface tied screen size to mode size
*/
if (ret)
{
RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
RRScreenSizeNotify (pScreen);
if (ret) {
RRCrtcNotify(crtc, mode, x, y, rotation, NULL, 1,
outputs);
RRScreenSizeNotify(pScreen);
}
}
}
#endif
}
if (ret)
{
int o;
RRTellChanged (pScreen);
if (ret) {
RRTellChanged(pScreen);
for (o = 0; o < numOutputs; o++)
RRPostPendingProperties (outputs[o]);
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
RRCrtcDestroy (RRCrtcPtr crtc)
RRCrtcDestroy(RRCrtcPtr crtc)
{
FreeResource (crtc->id, 0);
FreeResource(crtc->id, 0);
}
static int
RRCrtcDestroyResource (void * value, XID pid)
RRCrtcDestroyResource(void *value, XID pid)
{
RRCrtcPtr crtc = (RRCrtcPtr) value;
ScreenPtr pScreen = crtc->pScreen;
if (pScreen)
{
if (pScreen) {
rrScrPriv(pScreen);
int i;
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
if (pScrPriv->crtcs[i] == crtc)
{
memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
(pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr));
for (i = 0; i < pScrPriv->numCrtcs; i++) {
if (pScrPriv->crtcs[i] == crtc) {
memmove(pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
(pScrPriv->numCrtcs - (i + 1)) * sizeof(RRCrtcPtr));
--pScrPriv->numCrtcs;
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);
RRModeDestroy(crtc->mode);
xfree(crtc);
return 1;
}
......@@ -419,22 +790,19 @@ RRCrtcDestroyResource (void * value, XID pid)
*/
Bool
RRCrtcGammaSet (RRCrtcPtr crtc,
CARD16 *red,
CARD16 *green,
CARD16 *blue)
RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue)
{
Bool ret = TRUE;
#if RANDR_12_INTERFACE
ScreenPtr pScreen = crtc->pScreen;
#endif
memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16));
memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16));
memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16));
memcpy(crtc->gammaRed, red, crtc->gammaSize * sizeof(CARD16));
memcpy(crtc->gammaGreen, green, crtc->gammaSize * sizeof(CARD16));
memcpy(crtc->gammaBlue, blue, crtc->gammaSize * sizeof(CARD16));
#if RANDR_12_INTERFACE
if (pScreen)
{
if (pScreen) {
rrScrPriv(pScreen);
if (pScrPriv->rrCrtcSetGamma)
ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
......@@ -444,41 +812,69 @@ RRCrtcGammaSet (RRCrtcPtr crtc,
}
/*
* 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
*/
Bool
RRCrtcGammaNotify (RRCrtcPtr crtc)
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);
}
/*
......@@ -486,64 +882,125 @@ RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
*/
Bool
RRCrtcGammaSetSize (RRCrtcPtr crtc,
int size)
RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
{
CARD16 *gamma;
if (size == crtc->gammaSize)
return TRUE;
if (size)
{
gamma = xalloc (size * 3 * sizeof (CARD16));
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;
crtc->gammaBlue = gamma + size * 2;
crtc->gammaSize = size;
return TRUE;
}
/*
* Initialize crtc type
* Set the pending CRTC transformation
*/
Bool
RRCrtcInit (void)
{
RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource);
if (!RRCrtcType)
return FALSE;
RegisterResourceName (RRCrtcType, "CRTC");
return TRUE;
}
int
ProcRRGetCrtcInfo (ClientPtr client)
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)
{
REQUEST(xRRGetCrtcInfoReq);
xRRGetCrtcInfoReply rep;
RRCrtcPtr crtc;
CARD8 *extra;
unsigned long extraLen;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
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
#ifndef NXAGENT_SERVER
, "CRTC"
#endif
);
if (!RRCrtcType)
return FALSE;
return TRUE;
}
/*
* Initialize crtc type error value
*/
void
RRCrtcInitErrorValue(void)
{
#ifndef NXAGENT_SERVER
SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc);
#endif
}
int
ProcRRGetCrtcInfo(ClientPtr client)
{
REQUEST(xRRGetCrtcInfoReq);
xRRGetCrtcInfoReply rep;
RRCrtcPtr crtc;
CARD8 *extra;
unsigned long extraLen;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
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
......@@ -553,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 = (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;
RRCrtcGetScanoutSize (crtc, &width, &height);
rep.width = width;
rep.height = height;
}
rep.mode = mode ? mode->mode.id : 0;
rep.rotation = crtc->rotation;
rep.rotations = crtc->rotations;
......@@ -577,9 +1046,8 @@ ProcRRGetCrtcInfo (ClientPtr client)
rep.length = rep.nOutput + rep.nPossibleOutput;
extraLen = rep.length << 2;
if (extraLen)
{
extra = xalloc (extraLen);
if (extraLen) {
extra = xalloc(extraLen);
if (!extra)
return BadAlloc;
}
......@@ -589,20 +1057,18 @@ ProcRRGetCrtcInfo (ClientPtr client)
outputs = (RROutput *) extra;
possible = (RROutput *) (outputs + rep.nOutput);
for (i = 0; i < crtc->numOutputs; i++)
{
for (i = 0; i < crtc->numOutputs; i++) {
outputs[i] = crtc->outputs[i]->id;
if (client->swapped)
swapl (&outputs[i], n);
swapl(&outputs[i], n);
}
k = 0;
for (i = 0; i < pScrPriv->numOutputs; i++)
for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
if (pScrPriv->outputs[i]->crtcs[j] == crtc)
{
if (pScrPriv->outputs[i]->crtcs[j] == crtc) {
possible[k] = pScrPriv->outputs[i]->id;
if (client->swapped)
swapl (&possible[k], n);
swapl(&possible[k], n);
k++;
}
......@@ -620,18 +1086,17 @@ ProcRRGetCrtcInfo (ClientPtr client)
swaps(&rep.nOutput, n);
swaps(&rep.nPossibleOutput, n);
}
WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep);
if (extraLen)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *) &rep);
if (extraLen) {
WriteToClient(client, extraLen, (char *) extra);
xfree(extra);
}
return client->noClientException;
return Success;
}
int
ProcRRSetCrtcConfig (ClientPtr client)
ProcRRSetCrtcConfig(ClientPtr client)
{
REQUEST(xRRSetCrtcConfigReq);
xRRSetCrtcConfigReply rep;
......@@ -644,37 +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)));
crtc = LookupIDByType (stuff->crtc, RRCrtcType);
if (!crtc)
{
client->errorValue = stuff->crtc;
return RRErrorBase + BadRRCrtc;
}
if (stuff->mode == None)
{
VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
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;
}
else {
VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess);
if (numOutputs == 0)
return BadMatch;
}
if (numOutputs)
{
outputs = xalloc (numOutputs * sizeof (RROutputPtr));
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;
}
......@@ -682,59 +1145,58 @@ ProcRRSetCrtcConfig (ClientPtr client)
outputs = NULL;
outputIds = (RROutput *) (stuff + 1);
for (i = 0; i < numOutputs; i++)
{
outputs[i] = (RROutputPtr) LookupIDByType (outputIds[i], RROutputType);
if (!outputs[i])
{
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];
if (outputs)
xfree (outputs);
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);
if (j == outputs[i]->numCrtcs) {
xfree(outputs);
return BadMatch;
}
/* validate mode for this output */
for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
{
for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) {
RRModePtr m = (j < outputs[i]->numModes ?
outputs[i]->modes[j] :
outputs[i]->userModes[j - outputs[i]->numModes]);
if (m == mode)
break;
}
if (j == outputs[i]->numModes + outputs[i]->numUserModes)
{
if (outputs)
xfree (outputs);
if (j == outputs[i]->numModes + outputs[i]->numUserModes) {
xfree(outputs);
return BadMatch;
}
}
/* validate clones */
for (i = 0; i < numOutputs; i++)
{
for (j = 0; j < numOutputs; j++)
{
for (i = 0; i < numOutputs; i++) {
for (j = 0; j < numOutputs; j++) {
int k;
if (i == j)
continue;
for (k = 0; k < outputs[i]->numClones; k++)
{
for (k = 0; k < outputs[i]->numClones; k++) {
if (outputs[i]->clones[k] == outputs[j])
break;
}
if (k == outputs[i]->numClones)
{
if (outputs)
xfree (outputs);
if (k == outputs[i]->numClones) {
xfree(outputs);
return BadMatch;
}
}
......@@ -745,10 +1207,9 @@ ProcRRSetCrtcConfig (ClientPtr client)
time = ClientTimeToServerTime(stuff->timestamp);
if (!pScrPriv)
{
if (!pScrPriv) {
time = currentTime;
rep.status = RRSetConfigFailed;
status = RRSetConfigFailed;
goto sendReply;
}
......@@ -769,21 +1230,17 @@ ProcRRSetCrtcConfig (ClientPtr client)
* Invalid rotation
*/
client->errorValue = stuff->rotation;
if (outputs)
xfree (outputs);
xfree(outputs);
return BadValue;
}
if (mode)
{
if ((~crtc->rotations) & rotation)
{
if (mode) {
if ((~crtc->rotations) & rotation) {
/*
* requested rotation or reflection not supported by screen
*/
client->errorValue = stuff->rotation;
if (outputs)
xfree (outputs);
xfree(outputs);
return BadMatch;
}
......@@ -791,80 +1248,224 @@ 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 (pScrPriv->rrScreenSetSize && !crtc->transforms) {
int source_width;
int source_height;
PictTransform transform;
struct pixman_f_transform f_transform, f_inverse;
int width, height;
if ((rotation & 0xf) == RR_Rotate_90 || (rotation & 0xf) == RR_Rotate_270)
{
source_width = mode->mode.height;
source_height = mode->mode.width;
#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;
if (!RRCrtcSet(crtc, mode, stuff->x, stuff->y,
rotation, numOutputs, outputs)) {
status = RRSetConfigFailed;
goto sendReply;
}
status = RRSetConfigSuccess;
pScrPriv->lastSetTime = time;
if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y,
rotation, numOutputs, outputs))
{
rep.status = RRSetConfigFailed;
goto sendReply;
sendReply:
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);
}
rep.status = RRSetConfigSuccess;
pScrPriv->lastSetTime = time;
WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *) &rep);
sendReply:
if (outputs)
xfree (outputs);
return Success;
}
rep.type = X_Reply;
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
int
ProcRRGetPanning(ClientPtr client)
{
REQUEST(xRRGetPanningReq);
xRRGetPanningReply rep;
RRCrtcPtr crtc;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
BoxRec total;
BoxRec tracking;
INT16 border[4];
int n;
if (client->swapped)
{
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) {
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
ProcRRGetCrtcGammaSize (ClientPtr client)
ProcRRGetCrtcGammaSize(ClientPtr client)
{
REQUEST(xRRGetCrtcGammaSizeReq);
xRRGetCrtcGammaSizeReply reply;
......@@ -872,36 +1473,42 @@ 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);
swaps(&reply.sequenceNumber, n);
swapl(&reply.length, n);
swaps(&reply.size, n);
}
WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply);
return client->noClientException;
WriteToClient(client, sizeof(xRRGetCrtcGammaSizeReply), (char *) &reply);
return Success;
}
int
ProcRRGetCrtcGamma (ClientPtr client)
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;
......@@ -912,28 +1519,29 @@ 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);
swaps (&reply.size, n);
swaps(&reply.sequenceNumber, n);
swapl(&reply.length, n);
swaps(&reply.size, n);
}
WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply);
if (crtc->gammaSize)
{
WriteToClient(client, sizeof(xRRGetCrtcGammaReply), (char *) &reply);
if (crtc->gammaSize) {
memcpy(extra, crtc->gammaRed, len);
client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write;
WriteSwappedDataToClient (client, len, extra);
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
WriteSwappedDataToClient(client, len, extra);
xfree(extra);
}
return client->noClientException;
return Success;
}
int
ProcRRSetCrtcGamma (ClientPtr client)
ProcRRSetCrtcGamma(ClientPtr client)
{
REQUEST(xRRSetCrtcGammaReq);
RRCrtcPtr crtc;
......@@ -941,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;
......@@ -956,8 +1562,339 @@ ProcRRSetCrtcGamma (ClientPtr client)
green = red + crtc->gammaSize;
blue = green + crtc->gammaSize;
RRCrtcGammaSet (crtc, red, green, blue);
RRCrtcGammaSet(crtc, red, green, blue);
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;
}
......@@ -21,51 +21,66 @@
*/
#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)
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)
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);
}
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
return (client->noClientException);
#ifndef NXAGENT_SERVER
WriteToClient(client, sizeof(xRRQueryVersionReply), &rep);
#else
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *) &rep);
#endif
return Success;
}
static int
ProcRRSelectInput (ClientPtr client)
ProcRRSelectInput(ClientPtr client)
{
REQUEST(xRRSelectInputReq);
rrClientPriv(client);
......@@ -76,38 +91,46 @@ ProcRRSelectInput (ClientPtr client)
int rc;
REQUEST_SIZE_MATCH(xRRSelectInputReq);
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
#else
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess);
rc = pWin ? Success : BadWindow;
#endif
#endif
if (rc != Success)
return rc;
pHead = (RREventPtr *)SecurityLookupIDByType(client,
pWin->drawable.id, RREventType,
DixWriteAccess);
if (stuff->enable & (RRScreenChangeNotifyMask|
RRCrtcChangeNotifyMask|
RROutputChangeNotifyMask))
{
#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 |
RROutputPropertyNotifyMask |
RRProviderChangeNotifyMask |
RRProviderPropertyNotifyMask |
RRResourceChangeNotifyMask)) {
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
rrScrPriv(pScreen);
pRREvent = NULL;
if (pHead)
{
if (pHead) {
/* check for existing entry. */
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
if (pRREvent->client == client)
break;
}
if (!pRREvent)
{
if (!pRREvent) {
/* build the entry */
pRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
pRREvent = (RREventPtr) xalloc(sizeof(RREventRec));
if (!pRREvent)
return BadAlloc;
pRREvent->next = 0;
......@@ -118,9 +141,9 @@ ProcRRSelectInput (ClientPtr client)
* add a resource that will be deleted when
* the client goes away
*/
clientResource = FakeClientID (client->index);
clientResource = FakeClientID(client->index);
pRREvent->clientResource = clientResource;
if (!AddResource (clientResource, RRClientType, (void *)pRREvent))
if (!AddResource(clientResource, RRClientType, (void *) pRREvent))
return BadAlloc;
/*
* create a resource to contain a pointer to the list
......@@ -128,13 +151,12 @@ ProcRRSelectInput (ClientPtr client)
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if (!pHead)
{
pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
if (!pHead) {
pHead = (RREventPtr *) xalloc(sizeof(RREventPtr));
if (!pHead ||
!AddResource (pWin->drawable.id, RREventType, (void *)pHead))
{
FreeResource (clientResource, RT_NONE);
!AddResource(pWin->drawable.id, RREventType,
(void *) pHead)) {
FreeResource(clientResource, RT_NONE);
return BadAlloc;
}
*pHead = 0;
......@@ -145,47 +167,68 @@ 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,
if (CompareTimeStamps(pTimes->setTime,
pScrPriv->lastSetTime) != 0 ||
CompareTimeStamps (pTimes->configTime,
pScrPriv->lastConfigTime) != 0)
{
RRDeliverScreenEvent (client, pWin, pScreen);
CompareTimeStamps(pTimes->configTime,
pScrPriv->lastConfigTime) != 0) {
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.
*/
}
}
}
else if (stuff->enable == 0)
{
else if (stuff->enable == 0) {
/* delete the interest */
if (pHead) {
RREventPtr pNewRREvent = 0;
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
if (pRREvent->client == client)
break;
pNewRREvent = pRREvent;
}
if (pRREvent) {
FreeResource (pRREvent->clientResource, RRClientType);
FreeResource(pRREvent->clientResource, RRClientType);
if (pNewRREvent)
pNewRREvent->next = pRREvent->next;
else
*pHead = pRREvent->next;
xfree (pRREvent);
xfree(pRREvent);
}
}
}
else
{
else {
client->errorValue = stuff->enable;
return BadValue;
}
return Success;
}
int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
ProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
NULL, /* 1 ProcRandrOldGetScreenInfo */
......@@ -215,5 +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 */
};
......@@ -24,9 +24,10 @@
#ifdef RANDR_10_INTERFACE
static RRModePtr
RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
{
ScreenPtr pScreen = output->pScreen;
rrScrPriv(pScreen);
xRRModeInfo modeInfo;
char name[100];
......@@ -34,8 +35,8 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
int i;
RRModePtr *modes;
memset (&modeInfo, '\0', sizeof (modeInfo));
sprintf (name, "%dx%d", size->width, size->height);
memset(&modeInfo, '\0', sizeof(modeInfo));
snprintf(name, sizeof(name), "%dx%d", size->width, size->height);
modeInfo.width = size->width;
modeInfo.height = size->height;
......@@ -43,26 +44,29 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
modeInfo.vTotal = size->height;
modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height *
(CARD32) refresh);
modeInfo.nameLength = strlen (name);
mode = RRModeGet (&modeInfo, name);
modeInfo.nameLength = strlen(name);
mode = RRModeGet(&modeInfo, name);
if (!mode)
return NULL;
for (i = 0; i < output->numModes; i++)
if (output->modes[i] == mode)
{
RRModeDestroy (mode);
if (output->modes[i] == mode) {
RRModeDestroy(mode);
return mode;
}
if (output->numModes)
modes = xrealloc (output->modes,
(output->numModes + 1) * sizeof (RRModePtr));
#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)
{
RRModeDestroy (mode);
FreeResource (mode->mode.id, 0);
modes = xalloc(sizeof(RRModePtr));
if (!modes) {
RRModeDestroy(mode);
FreeResource(mode->mode.id, 0);
return NULL;
}
modes[output->numModes++] = mode;
......@@ -74,7 +78,7 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
}
static void
RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
{
rrScrPriv(pScreen);
RROutputPtr output;
......@@ -89,20 +93,16 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
* First time through, create a crtc and output and hook
* them together
*/
if (pScrPriv->numOutputs == 0 &&
pScrPriv->numCrtcs == 0)
{
crtc = RRCrtcCreate (pScreen, NULL);
if (pScrPriv->numOutputs == 0 && pScrPriv->numCrtcs == 0) {
crtc = RRCrtcCreate(pScreen, NULL);
if (!crtc)
return;
output = RROutputCreate (pScreen, "default", 7, NULL);
output = RROutputCreate(pScreen, "default", 7, NULL);
if (!output)
return;
RROutputSetCrtcs (output, &crtc, 1);
RROutputSetConnection (output, RR_Connected);
#ifdef RENDER
RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen));
#endif
RROutputSetCrtcs(output, &crtc, 1);
RROutputSetConnection(output, RR_Connected);
RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen));
}
output = pScrPriv->outputs[0];
......@@ -113,65 +113,61 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
return;
/* check rotations */
if (rotations != crtc->rotations)
{
if (rotations != crtc->rotations) {
crtc->rotations = rotations;
crtc->changed = TRUE;
pScrPriv->changed = TRUE;
}
/* regenerate mode list */
for (i = 0; i < pScrPriv->nSizes; i++)
{
for (i = 0; i < pScrPriv->nSizes; i++) {
RRScreenSizePtr size = &pScrPriv->pSizes[i];
int r;
if (size->nRates)
{
for (r = 0; r < size->nRates; r++)
{
mode = RROldModeAdd (output, size, size->pRates[r].rate);
if (size->nRates) {
for (r = 0; r < size->nRates; r++) {
mode = RROldModeAdd(output, size, size->pRates[r].rate);
if (i == pScrPriv->size &&
size->pRates[r].rate == pScrPriv->rate)
{
size->pRates[r].rate == pScrPriv->rate) {
newMode = mode;
}
}
xfree (size->pRates);
xfree(size->pRates);
}
else
{
mode = RROldModeAdd (output, size, 0);
else {
mode = RROldModeAdd(output, size, 0);
if (i == pScrPriv->size)
newMode = mode;
}
}
if (pScrPriv->nSizes)
xfree (pScrPriv->pSizes);
xfree(pScrPriv->pSizes);
pScrPriv->pSizes = NULL;
pScrPriv->nSizes = 0;
/* find size bounds */
for (i = 0; i < output->numModes + output->numUserModes; i++)
{
for (i = 0; i < output->numModes + output->numUserModes; i++) {
mode = (i < output->numModes ?
output->modes[i] :
output->userModes[i-output->numModes]);
output->userModes[i - output->numModes]);
width = mode->mode.width;
height = mode->mode.height;
if (width < minWidth) minWidth = width;
if (width > maxWidth) maxWidth = width;
if (height < minHeight) minHeight = height;
if (height > maxHeight) maxHeight = height;
if (width < minWidth)
minWidth = width;
if (width > maxWidth)
maxWidth = width;
if (height < minHeight)
minHeight = height;
if (height > maxHeight)
maxHeight = height;
}
RRScreenSetSizeRange (pScreen, minWidth, minHeight, maxWidth, maxHeight);
RRScreenSetSizeRange(pScreen, minWidth, minHeight, maxWidth, maxHeight);
/* 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
......@@ -179,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);
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++)
......@@ -199,9 +203,9 @@ RRGetInfo (ScreenPtr pScreen)
#if RANDR_10_INTERFACE
if (pScrPriv->nSizes)
RRScanOldConfig (pScreen, rotations);
RRScanOldConfig(pScreen, rotations);
#endif
RRTellChanged (pScreen);
RRTellChanged(pScreen);
return TRUE;
}
......@@ -209,19 +213,16 @@ RRGetInfo (ScreenPtr pScreen)
* Register the range of sizes for the screen
*/
void
RRScreenSetSizeRange (ScreenPtr pScreen,
RRScreenSetSizeRange(ScreenPtr pScreen,
CARD16 minWidth,
CARD16 minHeight,
CARD16 maxWidth,
CARD16 maxHeight)
CARD16 minHeight, CARD16 maxWidth, CARD16 maxHeight)
{
rrScrPriv (pScreen);
rrScrPriv(pScreen);
if (!pScrPriv)
return;
if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight &&
pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight)
{
pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight) {
return;
}
......@@ -229,14 +230,13 @@ RRScreenSetSizeRange (ScreenPtr pScreen,
pScrPriv->minHeight = minHeight;
pScrPriv->maxWidth = maxWidth;
pScrPriv->maxHeight = maxHeight;
pScrPriv->changed = TRUE;
RRSetChanged(pScreen);
pScrPriv->configChanged = TRUE;
}
#ifdef RANDR_10_INTERFACE
static Bool
RRScreenSizeMatches (RRScreenSizePtr a,
RRScreenSizePtr b)
RRScreenSizeMatches(RRScreenSizePtr a, RRScreenSizePtr b)
{
if (a->width != b->width)
return FALSE;
......@@ -250,13 +250,10 @@ RRScreenSizeMatches (RRScreenSizePtr a,
}
RRScreenSizePtr
RRRegisterSize (ScreenPtr pScreen,
short width,
short height,
short mmWidth,
short mmHeight)
RRRegisterSize(ScreenPtr pScreen,
short width, short height, short mmWidth, short mmHeight)
{
rrScrPriv (pScreen);
rrScrPriv(pScreen);
int i;
RRScreenSize tmp;
RRScreenSizePtr pNew;
......@@ -266,26 +263,30 @@ RRRegisterSize (ScreenPtr pScreen,
tmp.id = 0;
tmp.width = width;
tmp.height= height;
tmp.height = height;
tmp.mmWidth = mmWidth;
tmp.mmHeight = mmHeight;
tmp.pRates = 0;
tmp.nRates = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i]))
return &pScrPriv->pSizes[i];
pNew = xrealloc (pScrPriv->pSizes,
(pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
#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;
pScrPriv->pSizes = pNew;
return &pNew[pScrPriv->nSizes-1];
return &pNew[pScrPriv->nSizes - 1];
}
Bool RRRegisterRate (ScreenPtr pScreen,
RRScreenSizePtr pSize,
int rate)
Bool
RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate)
{
rrScrPriv(pScreen);
int i;
......@@ -298,8 +299,11 @@ Bool RRRegisterRate (ScreenPtr pScreen,
if (pSize->pRates[i].rate == rate)
return TRUE;
pNew = xrealloc (pSize->pRates,
(pSize->nRates + 1) * sizeof (RRScreenRate));
#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++];
......@@ -311,7 +315,7 @@ Bool RRRegisterRate (ScreenPtr pScreen,
Rotation
RRGetRotation(ScreenPtr pScreen)
{
RROutputPtr output = RRFirstOutput (pScreen);
RROutputPtr output = RRFirstOutput(pScreen);
if (!output)
return RR_Rotate_0;
......@@ -320,12 +324,10 @@ RRGetRotation(ScreenPtr pScreen)
}
void
RRSetCurrentConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
RRSetCurrentConfig(ScreenPtr pScreen,
Rotation rotation, int rate, RRScreenSizePtr pSize)
{
rrScrPriv (pScreen);
rrScrPriv(pScreen);
if (!pScrPriv)
return;
......
......@@ -38,25 +38,36 @@
/**************************************************************************/
#include "randrstr.h"
#include "registry.h"
RESTYPE RRModeType;
static Bool
RRModeEqual (xRRModeInfo *a, xRRModeInfo *b)
RRModeEqual(xRRModeInfo * a, xRRModeInfo * b)
{
if (a->width != b->width) return FALSE;
if (a->height != b->height) return FALSE;
if (a->dotClock != b->dotClock) return FALSE;
if (a->hSyncStart != b->hSyncStart) return FALSE;
if (a->hSyncEnd != b->hSyncEnd) return FALSE;
if (a->hTotal != b->hTotal) return FALSE;
if (a->hSkew != b->hSkew) return FALSE;
if (a->vSyncStart != b->vSyncStart) return FALSE;
if (a->vSyncEnd != b->vSyncEnd) return FALSE;
if (a->vTotal != b->vTotal) return FALSE;
if (a->nameLength != b->nameLength) return FALSE;
if (a->modeFlags != b->modeFlags) return FALSE;
if (a->width != b->width)
return FALSE;
if (a->height != b->height)
return FALSE;
if (a->dotClock != b->dotClock)
return FALSE;
if (a->hSyncStart != b->hSyncStart)
return FALSE;
if (a->hSyncEnd != b->hSyncEnd)
return FALSE;
if (a->hTotal != b->hTotal)
return FALSE;
if (a->hSkew != b->hSkew)
return FALSE;
if (a->vSyncStart != b->vSyncStart)
return FALSE;
if (a->vSyncEnd != b->vSyncEnd)
return FALSE;
if (a->vTotal != b->vTotal)
return FALSE;
if (a->nameLength != b->nameLength)
return FALSE;
if (a->modeFlags != b->modeFlags)
return FALSE;
return TRUE;
}
......@@ -67,33 +78,35 @@ static int num_modes;
static RRModePtr *modes;
static RRModePtr
RRModeCreate (xRRModeInfo *modeInfo,
const char *name,
ScreenPtr userScreen)
RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
{
RRModePtr mode, *newModes;
if (!RRInit ())
if (!RRInit())
return NULL;
mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1);
mode = xalloc(sizeof(RRModeRec) + modeInfo->nameLength + 1);
if (!mode)
return NULL;
mode->refcnt = 1;
mode->mode = *modeInfo;
mode->name = (char *) (mode + 1);
memcpy (mode->name, name, modeInfo->nameLength);
memcpy(mode->name, name, modeInfo->nameLength);
mode->name[modeInfo->nameLength] = '\0';
mode->userScreen = userScreen;
if (num_modes)
newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr));
#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));
newModes = xalloc(sizeof(RRModePtr));
if (!newModes)
{
xfree (mode);
if (!newModes) {
xfree(mode);
return NULL;
}
......@@ -104,29 +117,29 @@ RRModeCreate (xRRModeInfo *modeInfo,
}
modes = newModes;
modes[num_modes++] = mode;
/*
* give the caller a reference to this mode
*/
++mode->refcnt;
#ifdef DEBUG
fprintf(stderr, "RRModeCreate: num_modes [%d] new mode [%s] ([%p]) refcnt [%d]\n", num_modes, mode->name, mode, mode->refcnt);
fprintf(stderr,
"RRModeCreate: num_modes [%d] new mode [%s] ([%p]) refcnt [%d]\n",
num_modes, mode->name, mode, mode->refcnt);
#endif
return mode;
}
static RRModePtr
RRModeFindByName (const char *name,
CARD16 nameLength)
RRModeFindByName(const char *name, CARD16 nameLength)
{
int i;
RRModePtr mode;
for (i = 0; i < num_modes; i++)
{
for (i = 0; i < num_modes; i++) {
mode = modes[i];
if (mode->mode.nameLength == nameLength &&
!memcmp (name, mode->name, nameLength))
{
!memcmp(name, mode->name, nameLength)) {
return mode;
}
}
......@@ -134,20 +147,20 @@ RRModeFindByName (const char *name,
}
RRModePtr
RRModeGet (xRRModeInfo *modeInfo,
const char *name)
RRModeGet(xRRModeInfo * modeInfo, const char *name)
{
int i;
for (i = 0; i < num_modes; i++)
{
for (i = 0; i < num_modes; i++) {
RRModePtr mode = modes[i];
if (RRModeEqual (&mode->mode, modeInfo) &&
!memcmp (name, mode->name, modeInfo->nameLength))
{
if (RRModeEqual(&mode->mode, modeInfo) &&
!memcmp(name, mode->name, modeInfo->nameLength)) {
++mode->refcnt;
#ifdef DEBUG
fprintf(stderr, "RRModeGet: return existing mode [%s] ([%p]) refcnt [%d]\n", mode->name, mode, mode->refcnt);
fprintf(stderr,
"RRModeGet: return existing mode [%s] ([%p]) refcnt [%d]\n",
mode->name, mode, mode->refcnt);
#endif
return mode;
}
......@@ -155,33 +168,31 @@ RRModeGet (xRRModeInfo *modeInfo,
#ifdef DEBUG
{
RRModePtr mode = RRModeCreate (modeInfo, name, NULL);
fprintf(stderr, "RRModeGet: return new mode [%s] ([%p]) refcnt [%d]\n", mode->name, mode, mode->refcnt);
RRModePtr mode = RRModeCreate(modeInfo, name, NULL);
fprintf(stderr, "RRModeGet: return new mode [%s] ([%p]) refcnt [%d]\n",
mode->name, mode, mode->refcnt);
return mode;
}
#else
return RRModeCreate (modeInfo, name, NULL);
return RRModeCreate(modeInfo, name, NULL);
#endif
}
static RRModePtr
RRModeCreateUser (ScreenPtr pScreen,
xRRModeInfo *modeInfo,
const char *name,
int *error)
RRModeCreateUser(ScreenPtr pScreen,
xRRModeInfo * modeInfo, const char *name, int *error)
{
RRModePtr mode;
mode = RRModeFindByName (name, modeInfo->nameLength);
if (mode)
{
mode = RRModeFindByName(name, modeInfo->nameLength);
if (mode) {
*error = BadName;
return NULL;
}
mode = RRModeCreate (modeInfo, name, pScreen);
if (!mode)
{
mode = RRModeCreate(modeInfo, name, pScreen);
if (!mode) {
*error = BadAlloc;
return NULL;
}
......@@ -190,30 +201,32 @@ RRModeCreateUser (ScreenPtr pScreen,
}
RRModePtr *
RRModesForScreen (ScreenPtr pScreen, int *num_ret)
RRModesForScreen(ScreenPtr pScreen, int *num_ret)
{
rrScrPriv(pScreen);
int o, c, m;
RRModePtr *screen_modes;
int num_screen_modes = 0;
screen_modes = xalloc ((num_modes ? num_modes : 1) * sizeof (RRModePtr));
#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;
/*
* Add modes from all outputs
*/
for (o = 0; o < pScrPriv->numOutputs; o++)
{
for (o = 0; o < pScrPriv->numOutputs; o++) {
RROutputPtr output = pScrPriv->outputs[o];
int n;
for (m = 0; m < output->numModes + output->numUserModes; m++)
{
for (m = 0; m < output->numModes + output->numUserModes; m++) {
RRModePtr mode = (m < output->numModes ?
output->modes[m] :
output->userModes[m-output->numModes]);
output->userModes[m - output->numModes]);
for (n = 0; n < num_screen_modes; n++)
if (screen_modes[n] == mode)
break;
......@@ -226,13 +239,13 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
* make sure all available and active modes
* are visible to the client
*/
for (c = 0; c < pScrPriv->numCrtcs; c++)
{
for (c = 0; c < pScrPriv->numCrtcs; c++) {
RRCrtcPtr crtc = pScrPriv->crtcs[c];
RRModePtr mode = crtc->mode;
int n;
if (!mode) continue;
if (!mode)
continue;
for (n = 0; n < num_screen_modes; n++)
if (screen_modes[n] == mode)
break;
......@@ -242,8 +255,7 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
/*
* Add all user modes for this screen
*/
for (m = 0; m < num_modes; m++)
{
for (m = 0; m < num_modes; m++) {
RRModePtr mode = modes[m];
int n;
......@@ -261,62 +273,67 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
}
void
RRModeDestroy (RRModePtr mode)
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,
(num_modes - m - 1) * sizeof (RRModePtr));
for (m = 0; m < num_modes; m++) {
if (modes[m] == mode) {
memmove(modes + m, modes + m + 1,
(num_modes - m - 1) * sizeof(RRModePtr));
num_modes--;
if (!num_modes)
{
xfree (modes);
if (!num_modes) {
xfree(modes);
modes = NULL;
}
break;
}
}
#ifdef DEBUG
fprintf(stderr, "RRModeDestroy: destroyed mode [%s] ([%p])\n", mode->name, mode);
#endif
xfree (mode);
xfree(mode);
}
static int
RRModeDestroyResource (void * value, XID pid)
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);
RRModeDestroy((RRModePtr) value);
return 1;
}
/*
* Initialize mode type
*/
Bool
RRModeInit (void)
RRModeInit(void)
{
assert (num_modes == 0);
assert (modes == NULL);
RRModeType = CreateNewResourceType (RRModeDestroyResource);
assert(num_modes == 0);
assert(modes == NULL);
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)
ProcRRCreateMode(ClientPtr client)
{
REQUEST(xRRCreateModeReq);
xRRCreateModeReply rep;
......@@ -327,14 +344,15 @@ 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);
#else
REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
#endif
if (rc != Success)
return rc;
......@@ -342,103 +360,74 @@ 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);
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;
if (client->swapped)
{
int n;
rep = (xRRCreateModeReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.mode = mode->mode.id
};
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.mode, n);
}
WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep);
WriteToClient(client, sizeof(xRRCreateModeReply), (char *) &rep);
/* Drop out reference to this mode */
RRModeDestroy (mode);
return client->noClientException;
RRModeDestroy(mode);
return Success;
}
int
ProcRRDestroyMode (ClientPtr client)
ProcRRDestroyMode(ClientPtr client)
{
REQUEST(xRRDestroyModeReq);
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)
return BadAccess;
FreeResource (stuff->mode, 0);
FreeResource(stuff->mode, 0);
return Success;
}
int
ProcRRAddOutputMode (ClientPtr client)
ProcRRAddOutputMode(ClientPtr client)
{
REQUEST(xRRAddOutputModeReq);
RRModePtr mode;
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);
return RROutputAddUserMode(output, mode);
}
int
ProcRRDeleteOutputMode (ClientPtr client)
ProcRRDeleteOutputMode(ClientPtr client)
{
REQUEST(xRRDeleteOutputModeReq);
RRModePtr mode;
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);
return RROutputDeleteUserMode(output, mode);
}
/*
* 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;
}
/*
* 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;
......@@ -29,18 +29,32 @@ RESTYPE RROutputType;
* Notify the output of some change
*/
void
RROutputChanged (RROutputPtr output, Bool configChanged)
RROutputChanged(RROutputPtr output, Bool configChanged)
{
/* set changed bits on the master screen only */
ScreenPtr pScreen = output->pScreen;
rrScrPrivPtr mastersp;
output->changed = TRUE;
if (pScreen)
if (!pScreen)
return;
#ifndef NXAGENT_SERVER
if (pScreen->isGPU) {
ScreenPtr master = pScreen->current_master;
if (!master)
return;
mastersp = rrGetScrPriv(master);
}
else
#endif
{
rrScrPriv (pScreen);
pScrPriv->changed = TRUE;
if (configChanged)
pScrPriv->configChanged = TRUE;
mastersp = rrGetScrPriv(pScreen);
}
RRSetChanged(pScreen);
if (configChanged)
mastersp->configChanged = TRUE;
}
/*
......@@ -48,10 +62,8 @@ RROutputChanged (RROutputPtr output, Bool configChanged)
*/
RROutputPtr
RROutputCreate (ScreenPtr pScreen,
const char *name,
int nameLength,
void *devPrivate)
RROutputCreate(ScreenPtr pScreen,
const char *name, int nameLength, void *devPrivate)
{
RROutputPtr output;
RROutputPtr *outputs;
......@@ -63,23 +75,28 @@ RROutputCreate (ScreenPtr pScreen,
pScrPriv = rrGetScrPriv(pScreen);
if (pScrPriv->numOutputs)
outputs = xrealloc (pScrPriv->outputs,
(pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
#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));
outputs = xalloc(sizeof(RROutputPtr));
if (!outputs)
return FALSE;
pScrPriv->outputs = outputs;
output = xalloc (sizeof (RROutputRec) + nameLength + 1);
output = xalloc(sizeof(RROutputRec) + nameLength + 1);
if (!output)
return NULL;
output->id = FakeClientID (0);
output->id = FakeClientID(0);
output->pScreen = pScreen;
output->name = (char *) (output + 1);
output->nameLength = nameLength;
memcpy (output->name, name, nameLength);
memcpy(output->name, name, nameLength);
output->name[nameLength] = '\0';
output->connection = RR_UnknownConnection;
output->subpixelOrder = SubPixelUnknown;
......@@ -100,10 +117,13 @@ RROutputCreate (ScreenPtr pScreen,
output->changed = FALSE;
output->devPrivate = devPrivate;
if (!AddResource (output->id, RROutputType, (void *) output))
if (!AddResource(output->id, RROutputType, (void *) output))
return NULL;
pScrPriv->outputs[pScrPriv->numOutputs++] = output;
RRResourcesChanged(pScreen);
return output;
}
......@@ -111,94 +131,90 @@ RROutputCreate (ScreenPtr pScreen,
* Notify extension that output parameters have been changed
*/
Bool
RROutputSetClones (RROutputPtr output,
RROutputPtr *clones,
int numClones)
RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones)
{
RROutputPtr *newClones;
int i;
if (numClones == output->numClones)
{
if (numClones == output->numClones) {
for (i = 0; i < numClones; i++)
if (output->clones[i] != clones[i])
break;
if (i == numClones)
return TRUE;
}
if (numClones)
{
newClones = xalloc (numClones * sizeof (RROutputPtr));
if (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);
memcpy (newClones, clones, numClones * sizeof (RROutputPtr));
xfree(output->clones);
memcpy(newClones, clones, numClones * sizeof(RROutputPtr));
output->clones = newClones;
output->numClones = numClones;
RROutputChanged (output, TRUE);
RROutputChanged(output, TRUE);
return TRUE;
}
Bool
RROutputSetModes (RROutputPtr output,
RRModePtr *modes,
int numModes,
int numPreferred)
RROutputSetModes(RROutputPtr output,
RRModePtr * modes, int numModes, int numPreferred)
{
RRModePtr *newModes;
int i;
if (numModes == output->numModes && numPreferred == output->numPreferred)
{
if (numModes == output->numModes && numPreferred == output->numPreferred) {
for (i = 0; i < numModes; i++)
if (output->modes[i] != modes[i])
break;
if (i == numModes)
{
if (i == numModes) {
for (i = 0; i < numModes; i++)
RRModeDestroy (modes[i]);
RRModeDestroy(modes[i]);
return TRUE;
}
}
if (numModes)
{
newModes = xalloc (numModes * sizeof (RRModePtr));
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;
}
else
newModes = NULL;
if (output->modes)
{
if (output->modes) {
for (i = 0; i < output->numModes; i++)
RRModeDestroy (output->modes[i]);
xfree (output->modes);
RRModeDestroy(output->modes[i]);
xfree(output->modes);
}
memcpy (newModes, modes, numModes * sizeof (RRModePtr));
memcpy(newModes, modes, numModes * sizeof(RRModePtr));
output->modes = newModes;
output->numModes = numModes;
output->numPreferred = numPreferred;
RROutputChanged (output, TRUE);
RROutputChanged(output, TRUE);
return TRUE;
}
int
RROutputAddUserMode (RROutputPtr output,
RRModePtr mode)
RROutputAddUserMode(RROutputPtr output, RRModePtr mode)
{
int m;
ScreenPtr pScreen = output->pScreen;
rrScrPriv(pScreen);
RRModePtr *newModes;
/* Check to see if this mode is already listed for this output */
for (m = 0; m < output->numModes + output->numUserModes; m++)
{
for (m = 0; m < output->numModes + output->numUserModes; m++) {
RRModePtr e = (m < output->numModes ?
output->modes[m] :
output->userModes[m - output->numModes]);
......@@ -208,34 +224,37 @@ RROutputAddUserMode (RROutputPtr output,
/* Check with the DDX to see if this mode is OK */
if (pScrPriv->rrOutputValidateMode)
if (!pScrPriv->rrOutputValidateMode (pScreen, output, mode))
if (!pScrPriv->rrOutputValidateMode(pScreen, output, mode))
return BadMatch;
if (output->userModes)
newModes = xrealloc (output->userModes,
(output->numUserModes + 1) * sizeof (RRModePtr));
#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));
newModes = xalloc(sizeof(RRModePtr));
if (!newModes)
return BadAlloc;
output->userModes = newModes;
output->userModes[output->numUserModes++] = mode;
++mode->refcnt;
RROutputChanged (output, TRUE);
RRTellChanged (pScreen);
RROutputChanged(output, TRUE);
RRTellChanged(pScreen);
return Success;
}
int
RROutputDeleteUserMode (RROutputPtr output,
RRModePtr mode)
RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode)
{
int m;
/* Find this mode in the user mode list */
for (m = 0; m < output->numUserModes; m++)
{
for (m = 0; m < output->numUserModes; m++) {
RRModePtr e = output->userModes[m];
if (mode == e)
......@@ -249,166 +268,153 @@ RROutputDeleteUserMode (RROutputPtr output,
if (output->crtc && output->crtc->mode == mode)
return BadMatch;
memmove (output->userModes + m, output->userModes + m + 1,
(output->numUserModes - m - 1) * sizeof (RRModePtr));
memmove(output->userModes + m, output->userModes + m + 1,
(output->numUserModes - m - 1) * sizeof(RRModePtr));
output->numUserModes--;
RRModeDestroy (mode);
RRModeDestroy(mode);
return Success;
}
Bool
RROutputSetCrtcs (RROutputPtr output,
RRCrtcPtr *crtcs,
int numCrtcs)
RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs)
{
RRCrtcPtr *newCrtcs;
int i;
if (numCrtcs == output->numCrtcs)
{
if (numCrtcs == output->numCrtcs) {
for (i = 0; i < numCrtcs; i++)
if (output->crtcs[i] != crtcs[i])
break;
if (i == numCrtcs)
return TRUE;
}
if (numCrtcs)
{
newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr));
if (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);
memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr));
xfree(output->crtcs);
memcpy(newCrtcs, crtcs, numCrtcs * sizeof(RRCrtcPtr));
output->crtcs = newCrtcs;
output->numCrtcs = numCrtcs;
RROutputChanged (output, TRUE);
RROutputChanged(output, TRUE);
return TRUE;
}
Bool
RROutputSetConnection (RROutputPtr output,
CARD8 connection)
RROutputSetConnection(RROutputPtr output, CARD8 connection)
{
if (output->connection == connection)
return TRUE;
output->connection = connection;
RROutputChanged (output, TRUE);
RROutputChanged(output, TRUE);
return TRUE;
}
Bool
RROutputSetSubpixelOrder (RROutputPtr output,
int subpixelOrder)
RROutputSetSubpixelOrder(RROutputPtr output, int subpixelOrder)
{
if (output->subpixelOrder == subpixelOrder)
return TRUE;
output->subpixelOrder = subpixelOrder;
RROutputChanged (output, FALSE);
RROutputChanged(output, FALSE);
return TRUE;
}
Bool
RROutputSetPhysicalSize (RROutputPtr output,
int mmWidth,
int mmHeight)
RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight)
{
if (output->mmWidth == mmWidth && output->mmHeight == mmHeight)
return TRUE;
output->mmWidth = mmWidth;
output->mmHeight = mmHeight;
RROutputChanged (output, FALSE);
RROutputChanged(output, FALSE);
return TRUE;
}
void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
xRROutputChangeNotifyEvent oe;
rrScrPriv(pScreen);
RRCrtcPtr crtc = output->crtc;
RRModePtr mode = crtc ? crtc->mode : 0;
oe.type = RRNotify + RREventBase;
oe.subCode = RRNotify_OutputChange;
oe.sequenceNumber = client->sequence;
oe.timestamp = pScrPriv->lastSetTime.milliseconds;
oe.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
oe.window = pWin->drawable.id;
oe.output = output->id;
if (crtc)
{
oe.crtc = crtc->id;
oe.mode = mode ? mode->mode.id : None;
oe.rotation = crtc->rotation;
}
else
{
oe.crtc = None;
oe.mode = None;
oe.rotation = RR_Rotate_0;
}
oe.connection = output->connection;
oe.subpixelOrder = output->subpixelOrder;
WriteEventsToClient (client, 1, (xEvent *) &oe);
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);
}
/*
* Destroy a Output at shutdown
*/
void
RROutputDestroy (RROutputPtr output)
RROutputDestroy(RROutputPtr output)
{
FreeResource (output->id, 0);
FreeResource(output->id, 0);
}
static int
RROutputDestroyResource (void * value, XID pid)
RROutputDestroyResource(void *value, XID pid)
{
RROutputPtr output = (RROutputPtr) value;
ScreenPtr pScreen = output->pScreen;
int m;
if (pScreen)
{
if (pScreen) {
rrScrPriv(pScreen);
int i;
for (i = 0; i < pScrPriv->numOutputs; i++)
{
if (pScrPriv->outputs[i] == output)
{
memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1,
(pScrPriv->numOutputs - (i + 1)) * sizeof (RROutputPtr));
if (pScrPriv->primaryOutput == output)
pScrPriv->primaryOutput = NULL;
for (i = 0; i < pScrPriv->numOutputs; i++) {
if (pScrPriv->outputs[i] == output) {
memmove(pScrPriv->outputs + i, pScrPriv->outputs + i + 1,
(pScrPriv->numOutputs - (i + 1)) * sizeof(RROutputPtr));
--pScrPriv->numOutputs;
break;
}
}
RRResourcesChanged(pScreen);
}
if (output->modes)
{
if (output->modes) {
for (m = 0; m < output->numModes; m++)
RRModeDestroy (output->modes[m]);
xfree (output->modes);
RRModeDestroy(output->modes[m]);
xfree(output->modes);
}
for (m = 0; m < output->numUserModes; m++)
RRModeDestroy (output->userModes[m]);
if (output->userModes)
xfree (output->userModes);
if (output->crtcs)
xfree (output->crtcs);
if (output->clones)
xfree (output->clones);
RRDeleteAllOutputProperties (output);
xfree (output);
RRModeDestroy(output->userModes[m]);
xfree(output->userModes);
xfree(output->crtcs);
xfree(output->clones);
RRDeleteAllOutputProperties(output);
xfree(output);
return 1;
}
......@@ -416,19 +422,34 @@ RROutputDestroyResource (void * value, XID pid)
* Initialize output type
*/
Bool
RROutputInit (void)
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
ProcRRGetOutputInfo (ClientPtr client)
ProcRRGetOutputInfo(ClientPtr client)
{
REQUEST(xRRGetOutputInfoReq);
xRRGetOutputInfoReply rep;
......@@ -441,45 +462,39 @@ 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->numClones + bytes_to_int32(rep.nameLength)) << 2);
if (extraLen)
{
rep.length += extraLen >> 2;
extra = xalloc (extraLen);
if (extraLen) {
rep.length += bytes_to_int32(extraLen);
extra = xalloc(extraLen);
if (!extra)
return BadAlloc;
}
......@@ -491,28 +506,25 @@ ProcRRGetOutputInfo (ClientPtr client)
clones = (RROutput *) (modes + output->numModes + output->numUserModes);
name = (char *) (clones + output->numClones);
for (i = 0; i < output->numCrtcs; i++)
{
for (i = 0; i < output->numCrtcs; i++) {
crtcs[i] = output->crtcs[i]->id;
if (client->swapped)
swapl (&crtcs[i], n);
swapl(&crtcs[i], n);
}
for (i = 0; i < output->numModes + output->numUserModes; i++)
{
for (i = 0; i < output->numModes + output->numUserModes; i++) {
if (i < output->numModes)
modes[i] = output->modes[i]->mode.id;
else
modes[i] = output->userModes[i - output->numModes]->mode.id;
if (client->swapped)
swapl (&modes[i], n);
swapl(&modes[i], n);
}
for (i = 0; i < output->numClones; i++)
{
for (i = 0; i < output->numClones; i++) {
clones[i] = output->clones[i]->id;
if (client->swapped)
swapl (&clones[i], n);
swapl(&clones[i], n);
}
memcpy (name, output->name, output->nameLength);
memcpy(name, output->name, output->nameLength);
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
......@@ -522,15 +534,140 @@ 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);
}
WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep);
if (extraLen)
WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *) &rep);
if (extraLen) {
WriteToClient(client, extraLen, (char *) extra);
xfree(extra);
}
return Success;
}
static void
RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv, RROutputPtr output)
{
if (pScrPriv->primaryOutput == output)
return;
/* clear the old primary */
if (pScrPriv->primaryOutput) {
RROutputChanged(pScrPriv->primaryOutput, 0);
pScrPriv->primaryOutput = NULL;
}
/* set the new primary */
if (output) {
pScrPriv->primaryOutput = output;
RROutputChanged(output, 0);
}
pScrPriv->layoutChanged = TRUE;
RRTellChanged(pScreen);
}
int
ProcRRSetOutputPrimary(ClientPtr client)
{
REQUEST(xRRSetOutputPrimaryReq);
RROutputPtr output = NULL;
WindowPtr pWin;
rrScrPrivPtr pScrPriv;
int 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)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
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 client->noClientException;
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;
}
......@@ -21,6 +21,7 @@
*/
#include "randrstr.h"
#include "inputstr.h"
/*
* When the pointer moves, check to see if the specified position is outside
......@@ -31,7 +32,7 @@
*/
static Bool
RRCrtcContainsPosition (RRCrtcPtr crtc, int x, int y)
RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y)
{
RRModePtr mode = crtc->mode;
int scan_width, scan_height;
......@@ -39,7 +40,7 @@ RRCrtcContainsPosition (RRCrtcPtr crtc, int x, int y)
if (!mode)
return FALSE;
RRCrtcGetScanoutSize (crtc, &scan_width, &scan_height);
RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
if (crtc->x <= x && x < crtc->x + scan_width &&
crtc->y <= y && y < crtc->y + scan_height)
......@@ -51,16 +52,19 @@ 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);
rrScrPriv(pScreen);
int c;
RRCrtcPtr nearest = NULL;
int best = 0;
int best_dx = 0, best_dy = 0;
for (c = 0; c < pScrPriv->numCrtcs; c++)
{
for (c = 0; c < pScrPriv->numCrtcs; c++) {
RRCrtcPtr crtc = pScrPriv->crtcs[c];
RRModePtr mode = crtc->mode;
int dx, dy;
......@@ -72,51 +76,54 @@ RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
if (crtc == skip)
continue;
RRCrtcGetScanoutSize (crtc, &scan_width, &scan_height);
RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
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;
if (!nearest || dist < best)
{
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;
}
void
RRPointerMoved (ScreenPtr pScreen, int x, int y)
RRPointerMoved(ScreenPtr pScreen, int x, int y)
{
rrScrPriv (pScreen);
rrScrPriv(pScreen);
RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc;
int c;
/* Check last known CRTC */
if (pointerCrtc && RRCrtcContainsPosition (pointerCrtc, x, y))
if (pointerCrtc && RRCrtcContainsPosition(pointerCrtc, x, y))
return;
/* Check all CRTCs */
for (c = 0; c < pScrPriv->numCrtcs; c++)
{
for (c = 0; c < pScrPriv->numCrtcs; c++) {
RRCrtcPtr crtc = pScrPriv->crtcs[c];
if (RRCrtcContainsPosition (crtc, x, y))
{
if (RRCrtcContainsPosition(crtc, x, y)) {
/* Remember containing CRTC */
pScrPriv->pointerCrtc = crtc;
return;
......@@ -124,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)
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 */
}
}
......@@ -24,38 +24,81 @@
#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)
RRDeleteAllOutputProperties(RROutputPtr output)
{
RRPropertyPtr prop, next;
xRROutputPropertyNotifyEvent event;
for (prop = output->properties; prop; prop = next)
{
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);
}
}
static void
RRInitOutputPropertyValue (RRPropertyValuePtr property_value)
RRInitOutputPropertyValue(RRPropertyValuePtr property_value)
{
property_value->type = None;
property_value->format = 0;
......@@ -64,11 +107,11 @@ RRInitOutputPropertyValue (RRPropertyValuePtr property_value)
}
static RRPropertyPtr
RRCreateOutputProperty (Atom property)
RRCreateOutputProperty(Atom property)
{
RRPropertyPtr prop;
prop = (RRPropertyPtr)xalloc(sizeof(RRPropertyRec));
prop = (RRPropertyPtr) xalloc(sizeof(RRPropertyRec));
if (!prop)
return NULL;
prop->next = NULL;
......@@ -78,56 +121,32 @@ RRCreateOutputProperty (Atom property)
prop->immutable = FALSE;
prop->num_valid = 0;
prop->valid_values = NULL;
RRInitOutputPropertyValue (&prop->current);
RRInitOutputPropertyValue (&prop->pending);
RRInitOutputPropertyValue(&prop->current);
RRInitOutputPropertyValue(&prop->pending);
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)
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)
{
if (prop->propertyName == property) {
*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);
RRDeleteProperty(output, prop);
return;
}
}
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
void * value, Bool sendevent, Bool pending)
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;
......@@ -136,12 +155,11 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
size_in_bytes = format >> 3;
/* first see if property already exists */
prop = RRQueryOutputProperty (output, property);
if (!prop) /* just add to list */
{
prop = RRCreateOutputProperty (property);
prop = RRQueryOutputProperty(output, property);
if (!prop) { /* just add to list */
prop = RRCreateOutputProperty(property);
if (!prop)
return(BadAlloc);
return BadAlloc;
add = TRUE;
mode = PropModeReplace;
}
......@@ -156,25 +174,26 @@ 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;
else
total_len = prop_value->size + len;
if (mode == PropModeReplace || len > 0)
{
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);
RRDestroyOutputProperty(prop);
return BadAlloc;
}
new_value.size = len;
......@@ -198,31 +217,28 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
break;
}
if (new_data)
memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
memcpy((char *) new_data, (char *) value, len * size_in_bytes);
if (old_data)
memcpy ((char *) old_data, (char *) prop_value->data,
memcpy((char *) old_data, (char *) prop_value->data,
prop_value->size * size_in_bytes);
if (pending && pScrPriv->rrOutputSetProperty &&
!pScrPriv->rrOutputSetProperty(output->pScreen, output,
prop->propertyName, &new_value))
{
if (new_value.data)
xfree (new_value.data);
return (BadValue);
}
if (prop_value->data)
xfree (prop_value->data);
prop->propertyName, &new_value)) {
xfree(new_value.data);
if (add)
RRDestroyOutputProperty(prop);
return BadValue;
}
xfree(prop_value->data);
*prop_value = new_value;
}
else if (len == 0)
{
else if (len == 0) {
/* do nothing */
}
if (add)
{
if (add) {
prop->next = output->properties;
output->properties = prop;
}
......@@ -230,21 +246,22 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
if (pending && prop->is_pending)
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);
if (sendevent) {
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
RRPostPendingProperties (RROutputPtr output)
RRPostPendingProperties(RROutputPtr output)
{
RRPropertyValuePtr pending_value;
RRPropertyValuePtr current_value;
......@@ -255,8 +272,7 @@ RRPostPendingProperties (RROutputPtr output)
return TRUE;
output->pendingProperties = FALSE;
for (property = output->properties; property; property = property->next)
{
for (property = output->properties; property; property = property->next) {
/* Skip non-pending properties */
if (!property->is_pending)
continue;
......@@ -271,22 +287,21 @@ RRPostPendingProperties (RROutputPtr output)
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))
!memcmp(pending_value->data, current_value->data,
pending_value->size * (pending_value->format / 8)))
continue;
if (RRChangeOutputProperty (output, property->propertyName,
if (RRChangeOutputProperty(output, property->propertyName,
pending_value->type, pending_value->format,
PropModeReplace, pending_value->size,
pending_value->data, TRUE,
FALSE) != Success)
pending_value->data, TRUE, FALSE) != Success)
ret = FALSE;
}
return ret;
}
RRPropertyPtr
RRQueryOutputProperty (RROutputPtr output, Atom property)
RRQueryOutputProperty(RROutputPtr output, Atom property)
{
RRPropertyPtr prop;
......@@ -297,65 +312,80 @@ RRQueryOutputProperty (RROutputPtr output, Atom property)
}
RRPropertyValuePtr
RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending)
RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending)
{
RRPropertyPtr prop = RRQueryOutputProperty (output, property);
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
RRConfigureOutputProperty (RROutputPtr output, Atom property,
RRConfigureOutputProperty(RROutputPtr output, Atom property,
Bool pending, Bool range, Bool immutable,
int num_values, INT32 *values)
{
RRPropertyPtr prop = RRQueryOutputProperty (output, property);
RRPropertyPtr prop = RRQueryOutputProperty(output, property);
Bool add = FALSE;
INT32 *new_values;
if (!prop) {
prop = RRCreateOutputProperty(property);
if (!prop)
{
prop = RRCreateOutputProperty (property);
if (!prop)
return(BadAlloc);
return BadAlloc;
add = TRUE;
} else if (prop->immutable && !immutable)
return(BadAccess);
}
else if (prop->immutable && !immutable)
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;
}
new_values = xalloc (num_values * sizeof (INT32));
if (!new_values && num_values)
#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)
RRDestroyOutputProperty(prop);
return BadAlloc;
}
if (num_values)
memcpy (new_values, values, num_values * sizeof (INT32));
memcpy(new_values, values, num_values * sizeof(INT32));
/*
* Property moving from pending to non-pending
* loses any pending values
*/
if (prop->is_pending && !pending)
{
if (prop->pending.data)
xfree (prop->pending.data);
RRInitOutputPropertyValue (&prop->pending);
if (prop->is_pending && !pending) {
xfree(prop->pending.data);
RRInitOutputPropertyValue(&prop->pending);
}
prop->is_pending = pending;
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) {
......@@ -367,104 +397,109 @@ RRConfigureOutputProperty (RROutputPtr output, Atom property,
}
int
ProcRRListOutputProperties (ClientPtr client)
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);
rep.type = X_Reply;
rep.length = (numProps * sizeof(Atom)) >> 2;
rep.sequenceNumber = client->sequence;
rep.nAtoms = numProps;
if (client->swapped)
{
int n;
swaps (&rep.sequenceNumber, n);
swapl (&rep.length, n);
swaps (&rep.nAtoms, n);
#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 = (xRRListOutputPropertiesReply) {
.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;
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;
WriteToClient(client, sizeof(xRRListOutputPropertiesReply), (char*)&rep);
if (numProps)
{
client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
xfree(pAtoms);
}
return(client->noClientException);
return Success;
}
int
ProcRRQueryOutputProperty (ClientPtr client)
ProcRRQueryOutputProperty(ClientPtr client)
{
REQUEST(xRRQueryOutputPropertyReq);
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);
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;
swaps (&rep.sequenceNumber, n);
swapl (&rep.length, 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);
}
WriteToClient (client, sizeof (xRRQueryOutputPropertyReply), (char*)&rep);
if (prop->num_valid)
{
WriteToClient(client, sizeof(xRRQueryOutputPropertyReply), (char *) &rep);
if (prop->num_valid) {
memcpy(extra, prop->valid_values, prop->num_valid * sizeof(INT32));
client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32),
extra);
xfree(extra);
}
return(client->noClientException);
return Success;
}
int
ProcRRConfigureOutputProperty (ClientPtr client)
ProcRRConfigureOutputProperty(ClientPtr client)
{
REQUEST(xRRConfigureOutputPropertyReq);
RROutputPtr output;
......@@ -472,20 +507,17 @@ ProcRRConfigureOutputProperty (ClientPtr client)
REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
output = LookupOutput (client, stuff->output, DixReadAccess);
VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
if (!output)
return RRErrorBase + BadRROutput;
num_valid = stuff->length - (sizeof (xRRConfigureOutputPropertyReq) >> 2);
return RRConfigureOutputProperty (output, stuff->property,
stuff->pending, stuff->range,
FALSE, num_valid,
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
ProcRRChangeOutputProperty (ClientPtr client)
ProcRRChangeOutputProperty(ClientPtr client)
{
REQUEST(xRRChangeOutputPropertyReq);
RROutputPtr output;
......@@ -500,72 +532,75 @@ ProcRRChangeOutputProperty (ClientPtr client)
format = stuff->format;
mode = stuff->mode;
if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
(mode != PropModePrepend))
{
(mode != PropModePrepend)) {
client->errorValue = mode;
return BadValue;
}
if ((format != 8) && (format != 16) && (format != 32))
{
if ((format != 8) && (format != 16) && (format != 32)) {
client->errorValue = format;
return BadValue;
}
len = stuff->nUnits;
if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
if (len > bytes_to_int32((0xffffffff - sizeof(xChangePropertyReq))))
return BadLength;
sizeInBytes = format>>3;
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))
{
if (!ValidAtom(stuff->property)) {
client->errorValue = stuff->property;
return(BadAtom);
return BadAtom;
}
if (!ValidAtom(stuff->type))
{
if (!ValidAtom(stuff->type)) {
client->errorValue = stuff->type;
return(BadAtom);
return BadAtom;
}
err = RRChangeOutputProperty(output, stuff->property,
stuff->type, (int)format,
(int)mode, len, (void *)&stuff[1], TRUE, TRUE);
stuff->type, (int) format,
(int) mode, len, (void *) &stuff[1], TRUE,
TRUE);
if (err != Success)
return err;
else
return client->noClientException;
return Success;
}
int
ProcRRDeleteOutputProperty (ClientPtr client)
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))
{
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
ProcRRGetOutputProperty (ClientPtr client)
ProcRRGetOutputProperty(ClientPtr client)
{
REQUEST(xRRGetOutputPropertyReq);
RRPropertyPtr prop, *prev;
......@@ -573,103 +608,93 @@ 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;
if (!ValidAtom(stuff->property))
{
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))
{
if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
client->errorValue = stuff->delete;
return(BadValue);
return BadValue;
}
if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
{
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;
if (!prop)
{
reply = (xRRGetOutputPropertyReply) {
.type = X_Reply,
.sequenceNumber = client->sequence
};
if (!prop) {
reply.nItems = 0;
reply.length = 0;
reply.bytesAfter = 0;
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);
}
WriteToClient(client, sizeof(xRRGetOutputPropertyReply), &reply);
return(client->noClientException);
swaps(&reply.sequenceNumber, m);
swapl(&reply.length, m);
swapl(&reply.propertyType, m);
swapl(&reply.bytesAfter, m);
swapl(&reply.nItems, m);
}
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. */
if (((stuff->type != prop_value->type) &&
(stuff->type != AnyPropertyType))
)
{
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) {
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;
}
/*
* Return type, format, value to client
*/
n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */
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)
{
if (n < ind) {
client->errorValue = stuff->longOffset;
return BadValue;
}
......@@ -683,54 +708,53 @@ 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
reply.nItems = 0;
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);
if (stuff->delete && (reply.bytesAfter == 0)) {
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);
if (len)
{
memcpy(extra, (char *)prop_value->data + ind, len);
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;
case 32:
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
break;
case 16:
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
break;
default:
client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
break;
}
WriteSwappedDataToClient(client, len,
extra);
WriteSwappedDataToClient(client, len, extra);
xfree(extra);
}
if (stuff->delete && (reply.bytesAfter == 0))
{ /* delete the Property */
if (stuff->delete && (reply.bytesAfter == 0)) { /* delete the Property */
*prev = prop->next;
RRDestroyOutputProperty (prop);
RRDestroyOutputProperty(prop);
}
return(client->noClientException);
return Success;
}
/*
* 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);
}
/*
* 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;
}
......@@ -39,19 +39,15 @@
#include "randrstr.h"
extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
static CARD16
RR10CurrentSizeID (ScreenPtr pScreen);
RR10CurrentSizeID(ScreenPtr pScreen);
/*
* Edit connection information block so that new clients
* see the current screen size on connect
*/
static void
RREditConnectionInfo (ScreenPtr pScreen)
RREditConnectionInfo(ScreenPtr pScreen)
{
xConnSetup *connSetup;
char *vendor;
......@@ -63,22 +59,18 @@ RREditConnectionInfo (ScreenPtr pScreen)
int d;
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof (xConnSetup);
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);
while (screen != pScreen->myNum)
{
depth = (xDepth *) ((char *) root +
sizeof (xWindowRoot));
for (d = 0; d < root->nDepths; d++)
{
visual = (xVisualType *) ((char *) depth +
sizeof (xDepth));
sizeof(xPixmapFormat) *
screenInfo.numPixmapFormats);
while (screen != pScreen->myNum) {
depth = (xDepth *) ((char *) root + sizeof(xWindowRoot));
for (d = 0; d < root->nDepths; d++) {
visual = (xVisualType *) ((char *) depth + sizeof(xDepth));
depth = (xDepth *) ((char *) visual +
depth->nVisuals * sizeof (xVisualType));
depth->nVisuals * sizeof(xVisualType));
}
root = (xWindowRoot *) ((char *) depth);
screen++;
......@@ -90,63 +82,62 @@ RREditConnectionInfo (ScreenPtr pScreen)
}
void
RRSendConfigNotify (ScreenPtr pScreen)
RRSendConfigNotify(ScreenPtr pScreen)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
xEvent event;
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;
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 ? */
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;
.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;
DeliverEvents(pWin, &event, 1, NullWindow);
}
void
RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
{
rrScrPriv (pScreen);
xRRScreenChangeNotifyEvent se;
rrScrPriv(pScreen);
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;
se.heightInPixels = pScreen->width;
se.widthInMillimeters = pScreen->mmHeight;
se.heightInMillimeters = pScreen->mmWidth;
} else {
}
else {
se.widthInPixels = pScreen->width;
se.heightInPixels = pScreen->height;
se.widthInMillimeters = pScreen->mmWidth;
se.heightInMillimeters = pScreen->mmHeight;
}
WriteEventsToClient (client, 1, (xEvent *) &se);
WriteEventsToClient(client, 1, (xEvent *) (char *) &se);
}
/*
......@@ -155,7 +146,7 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
* the size of the screen
*/
void
RRScreenSizeNotify (ScreenPtr pScreen)
RRScreenSizeNotify(ScreenPtr pScreen)
{
rrScrPriv(pScreen);
/*
......@@ -172,43 +163,37 @@ 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);
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
RRTellChanged(pScreen);
RRSendConfigNotify(pScreen);
RREditConnectionInfo(pScreen);
RRPointerScreenConfigured (pScreen);
RRPointerScreenConfigured(pScreen);
/*
* Fix pointer bounds and location
*/
ScreenRestructured (pScreen);
ScreenRestructured(pScreen);
}
/*
* Request that the screen be resized
*/
Bool
RRScreenSizeSet (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
CARD32 mmWidth,
CARD32 mmHeight)
RRScreenSizeSet(ScreenPtr pScreen,
CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight)
{
rrScrPriv(pScreen);
#if RANDR_12_INTERFACE
if (pScrPriv->rrScreenSetSize)
{
if (pScrPriv->rrScreenSetSize) {
return (*pScrPriv->rrScreenSetSize) (pScreen,
width, height,
mmWidth, mmHeight);
width, height, mmWidth, mmHeight);
}
#endif
#if RANDR_10_INTERFACE
if (pScrPriv->rrSetConfig)
{
if (pScrPriv->rrSetConfig) {
return TRUE; /* can't set size separately */
}
#endif
......@@ -219,7 +204,7 @@ RRScreenSizeSet (ScreenPtr pScreen,
* Retrieve valid screen size range
*/
int
ProcRRGetScreenSizeRange (ClientPtr client)
ProcRRGetScreenSizeRange(ClientPtr client)
{
REQUEST(xRRGetScreenSizeRangeReq);
xRRGetScreenSizeRangeReply rep;
......@@ -227,43 +212,42 @@ 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);
#else
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
#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 (pScrPriv) {
if (!RRGetInfo(pScreen, FALSE))
return BadAlloc;
rep.minWidth = pScrPriv->minWidth;
rep.minHeight = pScrPriv->minHeight;
rep.maxWidth = pScrPriv->maxWidth;
rep.maxHeight = pScrPriv->maxHeight;
}
else
{
else {
rep.maxWidth = rep.minWidth = pScreen->width;
rep.maxHeight = rep.minHeight = pScreen->height;
}
if (client->swapped)
{
int n;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swaps(&rep.minWidth, n);
......@@ -271,12 +255,12 @@ ProcRRGetScreenSizeRange (ClientPtr client)
swaps(&rep.maxWidth, n);
swaps(&rep.maxHeight, n);
}
WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep);
return (client->noClientException);
WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *) &rep);
return Success;
}
int
ProcRRSetScreenSize (ClientPtr client)
ProcRRSetScreenSize(ClientPtr client)
{
REQUEST(xRRSetScreenSizeReq);
WindowPtr pWin;
......@@ -285,40 +269,39 @@ ProcRRSetScreenSize (ClientPtr client)
int i, rc;
REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
#else
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
#endif
if (rc != Success)
return rc;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width)
{
if (!pScrPriv)
return BadMatch;
if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) {
client->errorValue = stuff->width;
return BadValue;
}
if (stuff->height < pScrPriv->minHeight ||
pScrPriv->maxHeight < stuff->height)
{
pScrPriv->maxHeight < stuff->height) {
client->errorValue = stuff->height;
return BadValue;
}
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
for (i = 0; i < pScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pScrPriv->crtcs[i];
RRModePtr mode = crtc->mode;
if (mode)
{
if (mode) {
int source_width = mode->mode.width;
int source_height = mode->mode.height;
Rotation rotation = crtc->rotation;
if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270)
{
if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270) {
source_width = mode->mode.height;
source_height = mode->mode.width;
}
......@@ -328,23 +311,207 @@ ProcRRSetScreenSize (ClientPtr client)
return BadMatch;
}
}
if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
{
if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) {
client->errorValue = 0;
return BadValue;
}
if (!RRScreenSizeSet (pScreen,
if (!RRScreenSizeSet(pScreen,
stuff->width, stuff->height,
stuff->widthInMillimeters,
stuff->heightInMillimeters))
{
stuff->heightInMillimeters)) {
return BadMatch;
}
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;
......@@ -353,78 +520,84 @@ 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);
#else
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
#endif
if (rc != Success)
return rc;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
rep.pad = 0;
if (pScrPriv)
if (!RRGetInfo (pScreen))
if (query && pScrPriv)
if (!RRGetInfo(pScreen, query))
return BadAlloc;
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;
#ifndef NXAGENT_SERVER
if (!xorg_list_is_empty(&pScreen->output_slave_list))
return rrGetMultiScreenResources(client, query, pScreen);
#endif
if (!pScrPriv) {
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;
}
else
{
else {
RRModePtr *modes;
int num_modes;
modes = RRModesForScreen (pScreen, &num_modes);
modes = RRModesForScreen(pScreen, &num_modes);
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)
{
extra = xalloc (extraLen);
if (!extra)
{
xfree (modes);
if (extraLen) {
extra = xalloc(extraLen);
if (!extra) {
xfree(modes);
return BadAlloc;
}
}
......@@ -436,46 +609,54 @@ ProcRRGetScreenResources (ClientPtr client)
modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs);
names = (CARD8 *) (modeinfos + num_modes);
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
crtcs[i] = pScrPriv->crtcs[i]->id;
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++) {
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++)
{
for (i = 0; i < pScrPriv->numOutputs; i++) {
outputs[i] = pScrPriv->outputs[i]->id;
if (client->swapped)
swapl (&outputs[i], n);
swapl(&outputs[i], n);
}
for (i = 0; i < num_modes; i++)
{
for (i = 0; i < num_modes; i++) {
RRModePtr mode = modes[i];
modeinfos[i] = mode->mode;
if (client->swapped)
{
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);
}
memcpy (names, mode->name,
mode->mode.nameLength);
if (client->swapped) {
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);
}
memcpy(names, mode->name, mode->mode.nameLength);
names += mode->mode.nameLength;
}
xfree (modes);
assert (((((char *) names - (char *) extra) + 3) >> 2) == rep.length);
xfree(modes);
assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
}
if (client->swapped) {
......@@ -488,13 +669,25 @@ ProcRRGetScreenResources (ClientPtr client)
swaps(&rep.nModes, n);
swaps(&rep.nbytesNames, n);
}
WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *)&rep);
if (extraLen)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
WriteToClient(client, sizeof(xRRGetScreenResourcesReply),
(char *) (char *) &rep);
if (extraLen) {
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 {
......@@ -509,7 +702,7 @@ typedef struct _RR10Data {
* Convert 1.2 monitor data into 1.0 screen data
*/
static RR10DataPtr
RR10GetData (ScreenPtr pScreen, RROutputPtr output)
RR10GetData(ScreenPtr pScreen, RROutputPtr output)
{
RR10DataPtr data;
RRScreenSizePtr size;
......@@ -521,16 +714,15 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
Bool *used;
/* Make sure there is plenty of space for any combination */
data = malloc (sizeof (RR10DataRec) +
sizeof (RRScreenSize) * nmode +
sizeof (RRScreenRate) * nmode +
sizeof (Bool) * nmode);
data = xalloc(sizeof(RR10DataRec) +
sizeof(RRScreenSize) * nmode +
sizeof(RRScreenRate) * nmode + sizeof(Bool) * nmode);
if (!data)
return NULL;
size = (RRScreenSizePtr) (data + 1);
refresh = (RRScreenRatePtr) (size + nmode);
used = (Bool *) (refresh + nmode);
memset (used, '\0', sizeof (Bool) * nmode);
memset(used, '\0', sizeof(Bool) * nmode);
data->sizes = size;
data->nsize = 0;
data->nrefresh = 0;
......@@ -540,9 +732,9 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
/*
* find modes not yet listed
*/
for (o = 0; o < output->numModes + output->numUserModes; o++)
{
if (used[o]) continue;
for (o = 0; o < output->numModes + output->numUserModes; o++) {
if (used[o])
continue;
if (o < output->numModes)
mode = output->modes[o];
......@@ -556,7 +748,8 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
if (output->mmWidth && output->mmHeight) {
size[l].mmWidth = output->mmWidth;
size[l].mmHeight = output->mmHeight;
} else {
}
else {
size[l].mmWidth = pScreen->mmWidth;
size[l].mmHeight = pScreen->mmHeight;
}
......@@ -567,30 +760,26 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
/*
* Find all modes with matching size
*/
for (os = o; os < output->numModes + output->numUserModes; os++)
{
for (os = o; os < output->numModes + output->numUserModes; os++) {
if (os < output->numModes)
mode = output->modes[os];
else
mode = output->userModes[os - output->numModes];
if (mode->mode.width == size[l].width &&
mode->mode.height == size[l].height)
{
vRefresh = RRVerticalRefresh (&mode->mode);
mode->mode.height == size[l].height) {
vRefresh = RRVerticalRefresh(&mode->mode);
used[os] = TRUE;
for (r = 0; r < size[l].nRates; r++)
if (vRefresh == size[l].pRates[r].rate)
break;
if (r == size[l].nRates)
{
if (r == size[l].nRates) {
size[l].pRates[r].rate = vRefresh;
size[l].pRates[r].mode = mode;
size[l].nRates++;
data->nrefresh++;
}
if (mode == output->crtc->mode)
{
if (mode == output->crtc->mode) {
data->size = l;
data->refresh = vRefresh;
}
......@@ -601,92 +790,93 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
}
int
ProcRRGetScreenInfo (ClientPtr client)
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);
#else
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
#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;
output = RRFirstOutput(pScreen);
if (!pScrPriv || !output) {
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;
}
else
{
else {
int i, j;
xScreenSizes *size;
CARD16 *rates;
CARD8 *data8;
Bool has_rate = RRClientKnowsRates (client);
Bool has_rate = RRClientKnowsRates(client);
RR10DataPtr pData;
RRScreenSizePtr pSize;
pData = RR10GetData (pScreen, output);
pData = RR10GetData(pScreen, output);
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;
extraLen = rep.nSizes * sizeof (xScreenSizes);
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)
extraLen += rep.nrateEnts * sizeof (CARD16);
if (extraLen)
{
extra = (CARD8 *) xalloc (extraLen);
if (!extra)
{
xfree (pData);
extraLen += rep.nrateEnts * sizeof(CARD16);
if (extraLen) {
extra = (CARD8 *) xalloc(extraLen);
if (!extra) {
xfree(pData);
return BadAlloc;
}
}
......@@ -698,48 +888,42 @@ ProcRRGetScreenInfo (ClientPtr client)
*/
size = (xScreenSizes *) extra;
rates = (CARD16 *) (size + rep.nSizes);
for (i = 0; i < pData->nsize; i++)
{
for (i = 0; i < pData->nsize; i++) {
pSize = &pData->sizes[i];
size->widthInPixels = pSize->width;
size->heightInPixels = pSize->height;
size->widthInMillimeters = pSize->mmWidth;
size->heightInMillimeters = pSize->mmHeight;
if (client->swapped)
{
swaps (&size->widthInPixels, n);
swaps (&size->heightInPixels, n);
swaps (&size->widthInMillimeters, n);
swaps (&size->heightInMillimeters, n);
if (client->swapped) {
swaps(&size->widthInPixels, n);
swaps(&size->heightInPixels, n);
swaps(&size->widthInMillimeters, n);
swaps(&size->heightInMillimeters, n);
}
size++;
if (has_rate)
{
if (has_rate) {
*rates = pSize->nRates;
if (client->swapped)
{
swaps (rates, n);
if (client->swapped) {
swaps(rates, n);
}
rates++;
for (j = 0; j < pSize->nRates; j++)
{
for (j = 0; j < pSize->nRates; j++) {
*rates = pSize->pRates[j].rate;
if (client->swapped)
{
swaps (rates, n);
if (client->swapped) {
swaps(rates, n);
}
rates++;
}
}
}
xfree (pData);
xfree(pData);
data8 = (CARD8 *) rates;
if (data8 - (CARD8 *) extra != extraLen)
FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
(unsigned long)(data8 - (CARD8 *) extra), extraLen);
rep.length = (extraLen + 3) >> 2;
FatalError("RRGetScreenInfo bad extra len %ld != %ld\n",
(unsigned long) (data8 - (CARD8 *) extra), extraLen);
rep.length = bytes_to_int32(extraLen);
}
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
......@@ -752,22 +936,21 @@ ProcRRGetScreenInfo (ClientPtr client)
swaps(&rep.rate, n);
swaps(&rep.nrateEnts, n);
}
WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
if (extraLen)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *) &rep);
if (extraLen) {
WriteToClient(client, extraLen, (char *) extra);
xfree(extra);
}
return (client->noClientException);
return Success;
}
int
ProcRRSetScreenConfig (ClientPtr client)
ProcRRSetScreenConfig(ClientPtr client)
{
REQUEST(xRRSetScreenConfigReq);
xRRSetScreenConfigReply rep;
DrawablePtr pDraw;
int n, rc;
int rc;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
TimeStamp time;
......@@ -775,32 +958,34 @@ 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 ();
UpdateCurrentTime();
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
if (RRClientKnowsRates(client)) {
REQUEST_SIZE_MATCH(xRRSetScreenConfigReq);
has_rate = TRUE;
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
else {
REQUEST_SIZE_MATCH(xRR1_0SetScreenConfigReq);
has_rate = FALSE;
}
#ifndef NXAGENT_SERVER
#ifndef NXAGENT_SERVER
rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
#else
pDraw = SecurityLookupDrawable(stuff->drawable, client, SecurityWriteAccess);
#else /* !defined(NXAGENT_SERVER) */
pDraw =
SecurityLookupDrawable(stuff->drawable, client, SecurityWriteAccess);
rc = pDraw ? Success : BadDrawable;
#endif
#endif /* !defined(NXAGENT_SERVER) */
if (rc != Success)
return rc;
......@@ -810,20 +995,18 @@ ProcRRSetScreenConfig (ClientPtr client)
time = ClientTimeToServerTime(stuff->timestamp);
if (!pScrPriv)
{
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)
{
output = RRFirstOutput(pScreen);
if (!output) {
time = currentTime;
rep.status = RRSetConfigFailed;
status = RRSetConfigFailed;
goto sendReply;
}
......@@ -838,23 +1021,21 @@ ProcRRSetScreenConfig (ClientPtr client)
* timestamp, so using CompareTimeStamps here would cause randr to suddenly
* stop working after several hours have passed (freedesktop bug #6502).
*/
if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds)
{
rep.status = RRSetConfigInvalidConfigTime;
if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds) {
status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
pData = RR10GetData (pScreen, output);
pData = RR10GetData(pScreen, output);
if (!pData)
return BadAlloc;
if (stuff->sizeID >= pData->nsize)
{
if (stuff->sizeID >= pData->nsize) {
/*
* Invalid size ID
*/
client->errorValue = stuff->sizeID;
xfree (pData);
xfree(pData);
return BadValue;
}
pSize = &pData->sizes[stuff->sizeID];
......@@ -876,17 +1057,16 @@ ProcRRSetScreenConfig (ClientPtr client)
* Invalid rotation
*/
client->errorValue = stuff->rotation;
xfree (pData);
xfree(pData);
return BadValue;
}
if ((~crtc->rotations) & rotation)
{
if ((~crtc->rotations) & rotation) {
/*
* requested rotation or reflection not supported by screen
*/
client->errorValue = stuff->rotation;
xfree (pData);
xfree(pData);
return BadMatch;
}
......@@ -898,20 +1078,17 @@ ProcRRSetScreenConfig (ClientPtr client)
else
rate = 0;
if (rate)
{
for (i = 0; i < pSize->nRates; i++)
{
if (rate) {
for (i = 0; i < pSize->nRates; i++) {
if (pSize->pRates[i].rate == rate)
break;
}
if (i == pSize->nRates)
{
if (i == pSize->nRates) {
/*
* Invalid rate
*/
client->errorValue = rate;
xfree (pData);
xfree(pData);
return BadValue;
}
mode = pSize->pRates[i].mode;
......@@ -923,9 +1100,8 @@ ProcRRSetScreenConfig (ClientPtr client)
* Make sure the requested set-time is not older than
* the last set-time
*/
if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
{
rep.status = RRSetConfigInvalidTime;
if (CompareTimeStamps(time, pScrPriv->lastSetTime) < 0) {
status = RRSetConfigInvalidTime;
goto sendReply;
}
......@@ -935,104 +1111,98 @@ 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);
xfree(pData);
return BadValue;
}
if (height < pScrPriv->minHeight || pScrPriv->maxHeight < height) {
client->errorValue = height;
xfree (pData);
xfree(pData);
return BadValue;
}
if (width != pScreen->width || height != pScreen->height)
{
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;
for (c = 0; c < pScrPriv->numCrtcs; c++) {
if (!RRCrtcSet(pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0,
0, NULL)) {
status = RRSetConfigFailed;
/* XXX recover from failure */
goto sendReply;
}
}
if (!RRScreenSizeSet (pScreen, width, height,
pScreen->mmWidth, pScreen->mmHeight))
{
rep.status = RRSetConfigFailed;
if (!RRScreenSizeSet(pScreen, width, height,
pScreen->mmWidth, pScreen->mmHeight)) {
status = RRSetConfigFailed;
/* XXX recover from failure */
goto sendReply;
}
}
if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output))
rep.status = RRSetConfigFailed;
if (!RRCrtcSet(crtc, mode, 0, 0, stuff->rotation, 1, &output))
status = RRSetConfigFailed;
else {
pScrPriv->lastSetTime = time;
rep.status = RRSetConfigSuccess;
status = RRSetConfigSuccess;
}
/*
* XXX Configure other crtcs to mirror as much as possible
*/
sendReply:
sendReply:
if (pData)
xfree (pData);
xfree(pData);
rep.type = X_Reply;
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
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 = ?? */
};
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
if (client->swapped)
{
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.newTimestamp, n);
swapl(&rep.newConfigTimestamp, n);
swapl(&rep.root, n);
}
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *) &rep);
return (client->noClientException);
return Success;
}
static CARD16
RR10CurrentSizeID (ScreenPtr pScreen)
RR10CurrentSizeID(ScreenPtr pScreen)
{
CARD16 sizeID = 0xffff;
RROutputPtr output = RRFirstOutput (pScreen);
RROutputPtr output = RRFirstOutput(pScreen);
if (output)
{
RR10DataPtr data = RR10GetData (pScreen, output);
if (data)
{
if (output) {
RR10DataPtr data = RR10GetData(pScreen, output);
if (data) {
int i;
for (i = 0; i < data->nsize; i++)
if (data->sizes[i].width == pScreen->width &&
data->sizes[i].height == pScreen->height)
{
data->sizes[i].height == pScreen->height) {
sizeID = (CARD16) i;
break;
}
xfree (data);
xfree(data);
}
}
return sizeID;
......
......@@ -23,9 +23,10 @@
#include "randrstr.h"
static int
SProcRRQueryVersion (ClientPtr client)
SProcRRQueryVersion(ClientPtr client)
{
register int n;
int n;
REQUEST(xRRQueryVersionReq);
REQUEST_SIZE_MATCH(xRRQueryVersionReq);
......@@ -36,9 +37,10 @@ SProcRRQueryVersion (ClientPtr client)
}
static int
SProcRRGetScreenInfo (ClientPtr client)
SProcRRGetScreenInfo(ClientPtr client)
{
register int n;
int n;
REQUEST(xRRGetScreenInfoReq);
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
......@@ -48,19 +50,18 @@ SProcRRGetScreenInfo (ClientPtr client)
}
static int
SProcRRSetScreenConfig (ClientPtr client)
SProcRRSetScreenConfig(ClientPtr client)
{
register int n;
int n;
REQUEST(xRRSetScreenConfigReq);
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
swaps (&stuff->rate, n);
if (RRClientKnowsRates(client)) {
REQUEST_SIZE_MATCH(xRRSetScreenConfigReq);
swaps(&stuff->rate, n);
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
else {
REQUEST_SIZE_MATCH(xRR1_0SetScreenConfigReq);
}
swaps(&stuff->length, n);
......@@ -72,9 +73,10 @@ SProcRRSetScreenConfig (ClientPtr client)
}
static int
SProcRRSelectInput (ClientPtr client)
SProcRRSelectInput(ClientPtr client)
{
register int n;
int n;
REQUEST(xRRSelectInputReq);
REQUEST_SIZE_MATCH(xRRSelectInputReq);
......@@ -85,9 +87,10 @@ SProcRRSelectInput (ClientPtr client)
}
static int
SProcRRGetScreenSizeRange (ClientPtr client)
SProcRRGetScreenSizeRange(ClientPtr client)
{
int n;
REQUEST(xRRGetScreenSizeRangeReq);
REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq);
......@@ -97,9 +100,10 @@ SProcRRGetScreenSizeRange (ClientPtr client)
}
static int
SProcRRSetScreenSize (ClientPtr client)
SProcRRSetScreenSize(ClientPtr client)
{
int n;
REQUEST(xRRSetScreenSizeReq);
REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
......@@ -113,9 +117,10 @@ SProcRRSetScreenSize (ClientPtr client)
}
static int
SProcRRGetScreenResources (ClientPtr client)
SProcRRGetScreenResources(ClientPtr client)
{
int n;
REQUEST(xRRGetScreenResourcesReq);
REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
......@@ -125,10 +130,11 @@ SProcRRGetScreenResources (ClientPtr client)
}
static int
SProcRRGetOutputInfo (ClientPtr client)
SProcRRGetOutputInfo(ClientPtr client)
{
int n;
REQUEST(xRRGetOutputInfoReq);;
REQUEST(xRRGetOutputInfoReq);
REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
swaps(&stuff->length, n);
......@@ -138,9 +144,10 @@ SProcRRGetOutputInfo (ClientPtr client)
}
static int
SProcRRListOutputProperties (ClientPtr client)
SProcRRListOutputProperties(ClientPtr client)
{
int n;
REQUEST(xRRListOutputPropertiesReq);
REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq);
......@@ -150,9 +157,10 @@ SProcRRListOutputProperties (ClientPtr client)
}
static int
SProcRRQueryOutputProperty (ClientPtr client)
SProcRRQueryOutputProperty(ClientPtr client)
{
int n;
REQUEST(xRRQueryOutputPropertyReq);
REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
......@@ -163,11 +171,13 @@ SProcRRQueryOutputProperty (ClientPtr client)
}
static int
SProcRRConfigureOutputProperty (ClientPtr client)
SProcRRConfigureOutputProperty(ClientPtr client)
{
int n;
REQUEST(xRRConfigureOutputPropertyReq);
REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
swaps(&stuff->length, n);
swapl(&stuff->output, n);
swapl(&stuff->property, n);
......@@ -176,18 +186,19 @@ SProcRRConfigureOutputProperty (ClientPtr client)
}
static int
SProcRRChangeOutputProperty (ClientPtr client)
SProcRRChangeOutputProperty(ClientPtr client)
{
int n;
REQUEST(xRRChangeOutputPropertyReq);
REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq);
REQUEST_AT_LEAST_SIZE(xRRChangeOutputPropertyReq);
swaps(&stuff->length, n);
swapl(&stuff->output, n);
swapl(&stuff->property, n);
swapl(&stuff->type, n);
swapl(&stuff->nUnits, n);
switch(stuff->format) {
switch (stuff->format) {
case 8:
break;
case 16:
......@@ -204,9 +215,10 @@ SProcRRChangeOutputProperty (ClientPtr client)
}
static int
SProcRRDeleteOutputProperty (ClientPtr client)
SProcRRDeleteOutputProperty(ClientPtr client)
{
int n;
REQUEST(xRRDeleteOutputPropertyReq);
REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq);
......@@ -217,9 +229,10 @@ SProcRRDeleteOutputProperty (ClientPtr client)
}
static int
SProcRRGetOutputProperty (ClientPtr client)
SProcRRGetOutputProperty(ClientPtr client)
{
int n;
REQUEST(xRRGetOutputPropertyReq);
REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq);
......@@ -233,10 +246,12 @@ SProcRRGetOutputProperty (ClientPtr client)
}
static int
SProcRRCreateMode (ClientPtr client)
SProcRRCreateMode(ClientPtr client)
{
int n;
xRRModeInfo *modeinfo;
REQUEST(xRRCreateModeReq);
REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
......@@ -260,9 +275,10 @@ SProcRRCreateMode (ClientPtr client)
}
static int
SProcRRDestroyMode (ClientPtr client)
SProcRRDestroyMode(ClientPtr client)
{
int n;
REQUEST(xRRDestroyModeReq);
REQUEST_SIZE_MATCH(xRRDestroyModeReq);
......@@ -272,9 +288,10 @@ SProcRRDestroyMode (ClientPtr client)
}
static int
SProcRRAddOutputMode (ClientPtr client)
SProcRRAddOutputMode(ClientPtr client)
{
int n;
REQUEST(xRRAddOutputModeReq);
REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
......@@ -285,9 +302,10 @@ SProcRRAddOutputMode (ClientPtr client)
}
static int
SProcRRDeleteOutputMode (ClientPtr client)
SProcRRDeleteOutputMode(ClientPtr client)
{
int n;
REQUEST(xRRDeleteOutputModeReq);
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
......@@ -298,9 +316,10 @@ SProcRRDeleteOutputMode (ClientPtr client)
}
static int
SProcRRGetCrtcInfo (ClientPtr client)
SProcRRGetCrtcInfo(ClientPtr client)
{
int n;
REQUEST(xRRGetCrtcInfoReq);
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
......@@ -311,9 +330,10 @@ SProcRRGetCrtcInfo (ClientPtr client)
}
static int
SProcRRSetCrtcConfig (ClientPtr client)
SProcRRSetCrtcConfig(ClientPtr client)
{
int n;
REQUEST(xRRSetCrtcConfigReq);
REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
......@@ -330,9 +350,10 @@ SProcRRSetCrtcConfig (ClientPtr client)
}
static int
SProcRRGetCrtcGammaSize (ClientPtr client)
SProcRRGetCrtcGammaSize(ClientPtr client)
{
int n;
REQUEST(xRRGetCrtcGammaSizeReq);
REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
......@@ -342,9 +363,10 @@ SProcRRGetCrtcGammaSize (ClientPtr client)
}
static int
SProcRRGetCrtcGamma (ClientPtr client)
SProcRRGetCrtcGamma(ClientPtr client)
{
int n;
REQUEST(xRRGetCrtcGammaReq);
REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
......@@ -354,9 +376,10 @@ SProcRRGetCrtcGamma (ClientPtr client)
}
static int
SProcRRSetCrtcGamma (ClientPtr client)
SProcRRSetCrtcGamma(ClientPtr client)
{
int n;
REQUEST(xRRSetCrtcGammaReq);
REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
......@@ -367,7 +390,316 @@ SProcRRSetCrtcGamma (ClientPtr client)
return (*ProcRandrVector[stuff->randrReqType]) (client);
}
int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
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 */
NULL, /* 1 SProcRandrOldGetScreenInfo */
......@@ -382,11 +714,11 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRSetScreenSize, /* 7 */
SProcRRGetScreenResources, /* 8 */
SProcRRGetOutputInfo, /* 9 */
SProcRRListOutputProperties,/* 10 */
SProcRRListOutputProperties, /* 10 */
SProcRRQueryOutputProperty, /* 11 */
SProcRRConfigureOutputProperty, /* 12 */
SProcRRChangeOutputProperty,/* 13 */
SProcRRDeleteOutputProperty,/* 14 */
SProcRRChangeOutputProperty, /* 13 */
SProcRRDeleteOutputProperty, /* 14 */
SProcRRGetOutputProperty, /* 15 */
SProcRRCreateMode, /* 16 */
SProcRRDestroyMode, /* 17 */
......@@ -397,5 +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 */
};
/*
* 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;
}
}
/*
* 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_ */
......@@ -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,23 +113,25 @@ 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) {
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swaps(&rep.majorVersion, n);
swaps(&rep.minorVersion, n);
}
WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
return (client->noClientException);
WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *) &rep);
return Success;
}
int
......@@ -139,69 +140,56 @@ 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
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
if(rc != Success)
#endif
if (rc != Success)
return rc;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
if (pScrPriv)
{
if (pScrPriv) {
/* XXX do we need more than this? */
active = TRUE;
}
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.state = active;
rep.window = stuff->window;
if(client->swapped) {
swaps (&rep.sequenceNumber, n);
swapl (&rep.length, n);
swapl (&rep.window, n);
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;
WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *) &rep);
return Success;
}
static int
RRXineramaScreenCount (ScreenPtr pScreen)
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
RRXineramaScreenActive (ScreenPtr pScreen)
RRXineramaScreenActive(ScreenPtr pScreen)
{
return RRXineramaScreenCount (pScreen) > 0;
return RRXineramaScreenCount(pScreen) > 0;
}
int
......@@ -210,30 +198,34 @@ 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
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
#endif
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;
if(client->swapped) {
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;
WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *) &rep);
return Success;
}
int
......@@ -243,29 +235,33 @@ 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
#ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else
#else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow;
#endif
#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;
if(client->swapped) {
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);
swapl(&rep.width, n);
......@@ -273,30 +269,44 @@ ProcRRXineramaGetScreenSize(ClientPtr client)
swapl(&rep.window, n);
swapl(&rep.screen, n);
}
WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
return client->noClientException;
WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *) &rep);
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]);
if(client->swapped) {
register int n;
rep = (xXineramaIsActiveReply) {
.type = X_Reply,
.length = 0,
.sequenceNumber = client->sequence,
.state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN])
};
if (client->swapped) {
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
......@@ -304,56 +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);
if (RRXineramaScreenActive(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;
if(client->swapped) {
register int n;
rep = (xXineramaQueryScreensReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = bytes_to_int32(nmonitors * sz_XineramaScreenInfo),
.number = nmonitors
};
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.number, n);
}
WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
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
......@@ -380,55 +373,60 @@ ProcRRXineramaDispatch(ClientPtr client)
/* SProc */
static int
SProcRRXineramaQueryVersion (ClientPtr client)
SProcRRXineramaQueryVersion(ClientPtr client)
{
int n;
REQUEST(xPanoramiXQueryVersionReq);
register int n;
swaps(&stuff->length,n);
REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
return ProcRRXineramaQueryVersion(client);
}
static int
SProcRRXineramaGetState(ClientPtr client)
{
int n;
REQUEST(xPanoramiXGetStateReq);
register int n;
swaps (&stuff->length, n);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
swapl (&stuff->window, n);
swapl(&stuff->window, n);
return ProcRRXineramaGetState(client);
}
static int
SProcRRXineramaGetScreenCount(ClientPtr client)
{
int n;
REQUEST(xPanoramiXGetScreenCountReq);
register int n;
swaps (&stuff->length, n);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
swapl (&stuff->window, n);
swapl(&stuff->window, n);
return ProcRRXineramaGetScreenCount(client);
}
static int
SProcRRXineramaGetScreenSize(ClientPtr client)
{
int n;
REQUEST(xPanoramiXGetScreenSizeReq);
register int n;
swaps (&stuff->length, n);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
swapl (&stuff->window, n);
swapl (&stuff->screen, n);
swapl(&stuff->window, n);
swapl(&stuff->screen, n);
return ProcRRXineramaGetScreenSize(client);
}
static int
SProcRRXineramaIsActive(ClientPtr client)
{
int n;
REQUEST(xXineramaIsActiveReq);
register int n;
swaps (&stuff->length, n);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
return ProcRRXineramaIsActive(client);
}
......@@ -436,9 +434,10 @@ SProcRRXineramaIsActive(ClientPtr client)
static int
SProcRRXineramaQueryScreens(ClientPtr client)
{
int n;
REQUEST(xXineramaQueryScreensReq);
register int n;
swaps (&stuff->length, n);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
return ProcRRXineramaQueryScreens(client);
}
......@@ -464,19 +463,17 @@ SProcRRXineramaDispatch(ClientPtr client)
return BadRequest;
}
static void
RRXineramaResetProc(ExtensionEntry* extEntry)
{
}
void
RRXineramaExtensionInit(void)
{
#ifdef PANORAMIX
if(!noPanoramiXExtension)
if (!noPanoramiXExtension)
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
......@@ -485,9 +482,7 @@ RRXineramaExtensionInit(void)
if (screenInfo.numScreens > 1)
return;
(void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
(void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
ProcRRXineramaDispatch,
SProcRRXineramaDispatch,
RRXineramaResetProc,
StandardMinorOpcode);
SProcRRXineramaDispatch, NULL, StandardMinorOpcode);
}
......@@ -4,6 +4,7 @@ XCOMM $XFree86: xc/programs/Xserver/render/Imakefile,v 1.10 2002/11/23 02:38:15
SRCS = animcur.c \
filter.c \
glyph.c \
matrix.c \
miglyph.c \
miindex.c \
mipict.c \
......@@ -17,6 +18,7 @@ XCOMM $XFree86: xc/programs/Xserver/render/Imakefile,v 1.10 2002/11/23 02:38:15
OBJS = animcur.o \
filter.o \
glyph.o \
matrix.o \
miglyph.o \
miindex.o \
mipict.o \
......
......@@ -215,21 +215,30 @@ PictureFindFilter (ScreenPtr pScreen, char *name, int len)
}
static Bool
convolutionFilterValidateParams (PicturePtr pPicture,
convolutionFilterValidateParams (ScreenPtr pScreen,
int filter,
xFixed *params,
int nparams)
int nparams,
int* width,
int* height)
{
int w, h;
if (nparams < 3)
return FALSE;
if (xFixedFrac (params[0]) || xFixedFrac (params[1]))
return FALSE;
w = xFixedToInt (params[0]);
h = xFixedToInt (params[1]);
nparams -= 2;
if ((xFixedToInt (params[0]) * xFixedToInt (params[1])) > nparams)
if (w * h > nparams)
return FALSE;
*width = w;
*height = h;
return TRUE;
}
......@@ -271,10 +280,8 @@ PictureResetFilters (ScreenPtr pScreen)
int
SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams)
{
ScreenPtr pScreen;
PictFilterPtr pFilter;
xFixed *new_params;
int i;
ScreenPtr pScreen;
if (pPicture->pDrawable) {
pScreen = pPicture->pDrawable->pScreen;
......@@ -288,7 +295,7 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
if (!pFilter)
return BadName;
if (!pPicture->pDrawable) {
if (pPicture->pDrawable == NULL) {
int s;
/* For source pictures, the picture isn't tied to a screen. So, ensure
......@@ -303,8 +310,25 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
}
}
return SetPicturePictFilter (pPicture, pFilter, params, nparams);
}
int
SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
xFixed *params, int nparams)
{
ScreenPtr pScreen;
int i;
if (pPicture->pDrawable)
pScreen = pPicture->pDrawable->pScreen;
else
pScreen = screenInfo.screens[0];
if (pFilter->ValidateParams) {
if (!(*pFilter->ValidateParams) (pPicture, pFilter->id, params, nparams))
int width, height;
if (!(*pFilter->ValidateParams) (pScreen, pFilter->id, params, nparams, &width, &height))
return BadMatch;
}
else if (nparams) {
......@@ -312,7 +336,7 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
}
if (nparams != pPicture->filter_nparams) {
new_params = xalloc (nparams * sizeof (xFixed));
xFixed *new_params = xalloc (nparams * sizeof (xFixed));
if (!new_params && nparams)
return BadAlloc;
......@@ -324,8 +348,9 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
pPicture->filter_params[i] = params[i];
pPicture->filter = pFilter->id;
if (pPicture->pDrawable) {
PictureScreenPtr ps = GetPictureScreen (pScreen);
if (pPicture->pDrawable)
{
PictureScreenPtr ps = GetPictureScreen(pScreen);
int result;
result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter,
......@@ -335,5 +360,5 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
}
pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
return Success;
return ;
}
/*
* 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.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "misc.h"
#include "scrnintstr.h"
#include "os.h"
#include "regionstr.h"
#include "validate.h"
#include "windowstr.h"
#include "input.h"
#include "resource.h"
#include "colormapst.h"
#include "cursorstr.h"
#include "dixstruct.h"
#include "gcstruct.h"
#include "servermd.h"
#include "picturestr.h"
void
PictTransform_from_xRenderTransform(PictTransformPtr pict,
xRenderTransform * render)
{
pict->matrix[0][0] = render->matrix11;
pict->matrix[0][1] = render->matrix12;
pict->matrix[0][2] = render->matrix13;
pict->matrix[1][0] = render->matrix21;
pict->matrix[1][1] = render->matrix22;
pict->matrix[1][2] = render->matrix23;
pict->matrix[2][0] = render->matrix31;
pict->matrix[2][1] = render->matrix32;
pict->matrix[2][2] = render->matrix33;
}
void
xRenderTransform_from_PictTransform(xRenderTransform * render,
PictTransformPtr pict)
{
render->matrix11 = pict->matrix[0][0];
render->matrix12 = pict->matrix[0][1];
render->matrix13 = pict->matrix[0][2];
render->matrix21 = pict->matrix[1][0];
render->matrix22 = pict->matrix[1][1];
render->matrix23 = pict->matrix[1][2];
render->matrix31 = pict->matrix[2][0];
render->matrix32 = pict->matrix[2][1];
render->matrix33 = pict->matrix[2][2];
}
Bool
PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector)
{
return pixman_transform_point(transform, vector);
}
Bool
PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector)
{
return pixman_transform_point_3d(transform, vector);
}
......@@ -1892,71 +1892,3 @@ AddTraps (PicturePtr pPicture,
ValidatePicture (pPicture);
(*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
}
#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
Bool
PictureTransformPoint3d (PictTransformPtr transform,
PictVectorPtr vector)
{
PictVector result;
int i, j;
xFixed_32_32 partial;
xFixed_48_16 v;
for (j = 0; j < 3; j++)
{
v = 0;
for (i = 0; i < 3; i++)
{
partial = ((xFixed_48_16) transform->matrix[j][i] *
(xFixed_48_16) vector->vector[i]);
v += partial >> 16;
}
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
return FALSE;
result.vector[j] = (xFixed) v;
}
if (!result.vector[2])
return FALSE;
*vector = result;
return TRUE;
}
Bool
PictureTransformPoint (PictTransformPtr transform,
PictVectorPtr vector)
{
PictVector result;
int i, j;
xFixed_32_32 partial;
xFixed_48_16 v;
for (j = 0; j < 3; j++)
{
v = 0;
for (i = 0; i < 3; i++)
{
partial = ((xFixed_48_16) transform->matrix[j][i] *
(xFixed_48_16) vector->vector[i]);
v += partial >> 16;
}
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
return FALSE;
result.vector[j] = (xFixed) v;
}
if (!result.vector[2])
return FALSE;
for (j = 0; j < 2; j++)
{
partial = (xFixed_48_16) result.vector[j] << 16;
v = partial / result.vector[2];
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
return FALSE;
vector->vector[j] = (xFixed) v;
}
vector->vector[2] = xFixed1;
return TRUE;
}
......@@ -54,13 +54,10 @@ typedef struct _PictFormat {
IndexFormatRec index;
} PictFormatRec;
typedef struct _PictVector {
xFixed vector[3];
} PictVector, *PictVectorPtr;
typedef struct pixman_vector PictVector, *PictVectorPtr;
typedef struct pixman_transform PictTransform, *PictTransformPtr;
typedef struct _PictTransform {
xFixed matrix[3][3];
} PictTransform, *PictTransformPtr;
#define pict_f_transform pixman_f_transform
#define PICT_GRADIENT_STOPTABLE_SIZE 1024
#define SourcePictTypeSolidFill 0
......@@ -168,12 +165,14 @@ typedef struct _Picture {
SourcePictPtr pSourcePict;
} PictureRec;
typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
xFixed *params, int nparams);
typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id,
xFixed *params, int nparams,
int *width, int *height);
typedef struct {
char *name;
int id;
PictFilterValidateParamsProcPtr ValidateParams;
int width, height;
} PictFilterRec, *PictFilterPtr;
#define PictFilterNearest 0
......@@ -457,7 +456,12 @@ PictFilterPtr
PictureFindFilter (ScreenPtr pScreen, char *name, int len);
int
SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
xFixed *params, int nparams);
int
SetPictureFilter (PicturePtr pPicture, char *name, int len,
xFixed *params, int nparams);
Bool
PictureFinishInit (void);
......@@ -657,4 +661,22 @@ void PanoramiXRenderInit (void);
void PanoramiXRenderReset (void);
#endif
/*
* matrix.c
*/
extern _X_EXPORT void
PictTransform_from_xRenderTransform(PictTransformPtr pict,
xRenderTransform * render);
extern _X_EXPORT void
xRenderTransform_from_PictTransform(xRenderTransform * render,
PictTransformPtr pict);
extern _X_EXPORT Bool
PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector);
extern _X_EXPORT Bool
PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector);
#endif /* _PICTURESTR_H_ */
......@@ -2663,7 +2663,7 @@ PanoramiXRenderCreatePicture (ClientPtr client)
newPict->info[0].id = stuff->pid;
if (refDraw->type == XRT_WINDOW &&
stuff->drawable == WindowTable[0]->drawable.id)
stuff->drawable == screenInfo.screens[0]->root->drawable.id)
{
newPict->u.pict.root = TRUE;
}
......
......@@ -616,7 +616,7 @@ ReplaceCursor (CursorPtr pCursor,
}
}
/* this "knows" that WindowHasNewCursor doesn't depend on it's argument */
WindowHasNewCursor (WindowTable[0]);
WindowHasNewCursor (screenInfo.screens[0]->root);
}
static Bool
......
......@@ -49,6 +49,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "inputstr.h"
#include "opaque.h"
#include "property.h"
#include "scrnintstr.h"
#define XKBSRV_NEED_FILE_FUNCS
#include <nx-X11/extensions/XKBsrv.h>
#include <nx-X11/extensions/XKBgeom.h>
......@@ -230,7 +231,7 @@ char * pval;
ErrorF("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
out,len);
}
ChangeWindowProperty(WindowTable[0],name,XA_STRING,8,PropModeReplace,
ChangeWindowProperty(screenInfo.screens[0]->root,name,XA_STRING,8,PropModeReplace,
len,pval,True);
DEALLOCATE_LOCAL(pval);
return True;
......
#!/bin/sh
where=`dirname $0`
git ls-files | grep '\.[chm]$' | xargs sh "$where"/x-indent.sh
#!/bin/sh
# We want GNU indent, so first search for gindent to avoid /usr/bin/indent
# on the BSDs, which won't work for us
INDENT=`which gnuindent || which gindent || which indent`
if [ -z "${INDENT}" ] ; then
echo "Could not find indent, sorry..." >&2
exit 1
fi
$INDENT -linux -bad -bap -blf -bli0 -cbi0 -cdw -nce -cs -i4 -lc80 -psl -nbbo \
-nbc -psl -nbfda -nut -nss -T pointer -T ScreenPtr -T ScrnInfoPtr -T pointer \
-T DeviceIntPtr -T DevicePtr -T ClientPtr -T CallbackListPtr \
-T CallbackProcPtr -T OsTimerPtr -T CARD32 -T CARD16 -T CARD8 \
-T INT32 -T INT16 -T INT8 -T Atom -T Time -T WindowPtr -T DrawablePtr \
-T PixmapPtr -T ColormapPtr -T CursorPtr -T Font -T XID -T Mask \
-T BlockHandlerProcPtr -T WakeupHandlerProcPtr -T RegionPtr \
-T InternalEvent -T GrabPtr -T Timestamp -T Bool -T TimeStamp \
-T xEvent -T DeviceEvent -T RawDeviceEvent -T GrabMask -T Window \
-T Drawable -T FontPtr -T CallbackPtr -T XIPropertyValuePtr \
-T GrabParameters -T deviceKeyButtonPointer -T TouchOwnershipEvent \
-T xGenericEvent -T DeviceChangedEvent -T GCPtr -T BITS32 \
-T xRectangle -T BoxPtr -T RegionRec -T ValuatorMask -T KeyCode \
-T KeySymsPtr -T XkbDescPtr -T InputOption -T XI2Mask -T DevUnion \
-T DevPrivateKey -T DevScreenPrivateKey -T PropertyPtr -T RESTYPE \
-T XkbAction -T XkbChangesPtr -T XkbControlsPtr -T PrivatePtr -T pmWait \
-T _XFUNCPROTOBEGIN -T _XFUNCPROTOEND -T _X_EXPORT "$@"
......@@ -29,7 +29,7 @@ BuildRequires: fdupes
BuildRequires: pkgconfig(expat)
BuildRequires: pkgconfig(libpng)
BuildRequires: pkgconfig(libxml-2.0)
BuildRequires: pkgconfig(pixman-1)
BuildRequires: pkgconfig(pixman-1) >= 0.13.2
BuildRequires: pkgconfig(x11)
BuildRequires: pkgconfig(xext)
BuildRequires: pkgconfig(xpm)
......@@ -45,7 +45,7 @@ BuildRequires: pkgconfig(xinerama)
BuildRequires: libexpat-devel
BuildRequires: libpng-devel
BuildRequires: libxml2-devel
BuildRequires: pixman-devel
BuildRequires: pixman-devel >= 0.13.2
BuildRequires: xorg-x11-libX11-devel
BuildRequires: xorg-x11-libXext-devel
BuildRequires: xorg-x11-libXpm-devel
......@@ -65,7 +65,7 @@ BuildRequires: xorg-x11-util-devel
BuildRequires: expat-devel
BuildRequires: libpng-devel
BuildRequires: libxml2-devel
BuildRequires: pixman-devel
BuildRequires: pixman-devel >= 0.13.2
BuildRequires: libX11-devel
BuildRequires: libXext-devel
BuildRequires: libXpm-devel
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment