From 2d776b14fddc5ec70c97aa82672f3a7c9caef6a3 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 5 May 2015 10:24:24 +0200 Subject: library clean-up: Don't build libNX_Xinerama anymore. Use system's libXinerama shared library. (Fixes ArcticaProject/nx-libs#49). This commit goes along with a patch from Ulrich Sibiller who managed to move the Xinerama awareness for NX sessions into the Xserver code. This makes Xinerama support for NX in libNX_Xinerama.so obsolete. Fixes ArcticaProject/nx-libs#49 --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 491a92c2f..2f70334d4 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -79,6 +79,10 @@ is" without express or implied warranty. #include "X11/include/Xrandr_nxagent.h" +#include +#include "X11/include/Xinerama_nxagent.h" + + #define GC XlibGC #define Font XlibFont #define KeySym XlibKeySym -- cgit v1.2.3 From c6482d24fff982d5e11636167c719766f8207d48 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sat, 2 May 2015 21:53:25 +0200 Subject: Reimplement xinerama via randr in nxagent (not libNX_Xinerama). (Fixes ArcticaProject/nx-libs#23). No more xinerama faking, just use existing xrandr extension and initalize it properly. Xinerama then works automatically. Fixes ArcticaProject/nx-libs#23 --- nx-X11/programs/Xserver/hw/nxagent/Events.c | 46 ++- nx-X11/programs/Xserver/hw/nxagent/Extensions.c | 36 ++ nx-X11/programs/Xserver/hw/nxagent/Options.c | 2 + nx-X11/programs/Xserver/hw/nxagent/Options.h | 11 + nx-X11/programs/Xserver/hw/nxagent/Screen.c | 428 ++++++++++++++++++++---- 5 files changed, 452 insertions(+), 71 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c index 9f7d6280f..03b14f0dc 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Events.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c @@ -568,6 +568,10 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen) { XSizeHints sizeHints; + #ifdef DEBUG + fprintf(stderr, "nxagentSwitchResizeMode called.\n"); + #endif + int desktopResize = nxagentOption(DesktopResize); nxagentChangeOption(DesktopResize, !desktopResize); @@ -3366,7 +3370,9 @@ int nxagentHandleConfigureNotify(XEvent* X) if (nxagentOption(DesktopResize) == 1) { if (nxagentOption(Width) != X -> xconfigure.width || - nxagentOption(Height) != X -> xconfigure.height) + nxagentOption(Height) != X -> xconfigure.height || + nxagentOption(X) != X -> xconfigure.x || + nxagentOption(Y) != X -> xconfigure.y) { Bool newEvents = False; @@ -3423,11 +3429,16 @@ int nxagentHandleConfigureNotify(XEvent* X) nxagentMoveViewport(pScreen, 0, 0); + /* if in shadowing mode or if neither size nor position have + changed we do not need to adjust RandR */ + /* FIXME: Comment makes no sense */ if (nxagentOption(Shadow) == 1 || (nxagentOption(Width) == nxagentOption(RootWidth) && - nxagentOption(Height) == nxagentOption(RootHeight))) + nxagentOption(Height) == nxagentOption(RootHeight) && + nxagentOption(X) == nxagentOption(RootX) && + nxagentOption(Y) == nxagentOption(RootY))) { - doRandR = 0; + doRandR = False; } nxagentChangeOption(Width, X -> xconfigure.width); @@ -3466,12 +3477,31 @@ int nxagentHandleConfigureNotify(XEvent* X) #endif nxagentChangeScreenConfig(0, nxagentOption(Width), - nxagentOption(Height), 0, 0); + nxagentOption(Height), 0, 0); } } return 1; } + else + { + if (X -> xconfigure.window == DefaultRootWindow(nxagentDisplay)) + { + #ifdef TEST + fprintf(stderr, "nxagentHandleConfigureNotify: remote root window has changed: %d,%d %dx%d\n", X -> xconfigure.x, X -> xconfigure.y, X -> xconfigure.width, X -> xconfigure.height); + #endif + + nxagentChangeOption(RootX, X -> xconfigure.x); + nxagentChangeOption(RootY, X -> xconfigure.y); + nxagentChangeOption(RootWidth, X -> xconfigure.width); + nxagentChangeOption(RootHeight, X -> xconfigure.height); + + nxagentChangeScreenConfig(0, nxagentOption(Width), + nxagentOption(Height), 0, 0); + + return 1; + } + } } return 0; @@ -4416,6 +4446,10 @@ int nxagentHandleRRScreenChangeNotify(XEvent *X) { XRRScreenChangeNotifyEvent *Xr; + #ifdef DEBUG + fprintf(stderr, "nxagentHandleRRScreenChangeNotify called.\n"); + #endif + Xr = (XRRScreenChangeNotifyEvent *) X; nxagentResizeScreen(screenInfo.screens[DefaultScreen(nxagentDisplay)], Xr -> width, Xr -> height, @@ -4504,6 +4538,10 @@ int nxagentWaitEvents(Display *dpy, struct timeval *tm) { XEvent ev; + #ifdef DEBUG + fprintf(stderr, "nxagentWaitEvents called.\n"); + #endif + NXFlushDisplay(dpy, NXFlushLink); /* diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c index 6dce644ae..103eaa92c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c @@ -35,6 +35,11 @@ static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, static int nxagentRandRInitSizes(ScreenPtr pScreen); +static Bool nxagentRandRCrtcSet (ScreenPtr pScreen, RRCrtcPtr crtc, + RRModePtr mode, int x, int y, + Rotation rotation, int numOutputs, + RROutputPtr *outputs); + #ifdef __DARWIN__ void DarwinHandleGUI(int argc, char *argv[]) @@ -83,6 +88,8 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) fprintf(stderr, "Warning: Failed to initialize the RandR extension.\n"); } + + /* FIXME: do we need this at all with the new rand/xinerama stuff? */ nxagentRandRInitSizes(pScreen); /* @@ -97,6 +104,7 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) #if RANDR_12_INTERFACE pRandRScrPriv -> rrScreenSetSize = nxagentRandRScreenSetSize; + pRandRScrPriv -> rrCrtcSet = nxagentRandRCrtcSet; #endif #if RANDR_10_INTERFACE @@ -104,6 +112,34 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) #endif } +void +RRResetProc (ExtensionEntry *extEntry) +{ + fprintf(stderr, "RANDR going down - NX version\n"); +} + + + +#if RANDR_12_INTERFACE +/* + * Request that the Crtc be reconfigured + */ + +static Bool +nxagentRandRCrtcSet (ScreenPtr pScreen, + RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + return RRCrtcNotify(crtc, mode, x, y, rotation, numOutputs, outputs); +} +#endif + + int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations) { /* diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c index 7eac3d8a2..dbe200273 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Options.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c @@ -154,6 +154,8 @@ void nxagentInitOptions() nxagentOptions.CopyBufferSize = COPY_UNLIMITED; nxagentOptions.ImageRateLimit = 0; + + nxagentOptions.Xinerama = 0; } /* diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h index 0e4869926..5bf1597d5 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Options.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h @@ -388,6 +388,17 @@ typedef struct _AgentOptions int NoRootlessExit; + /* + * Store if the user wants Xinerama. There's a variable called + * noPanoramiXExtension in os/utils.c but we cannot rely on that + * because RandR and Panoramix change its value when trying to + * initialize. So we use this variable to save the user preference + * provided by the -/+xinerama parameter before initalizing those + * extensions. + */ + + int Xinerama; + } AgentOptionsRec; typedef AgentOptionsRec *AgentOptionsPtr; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 2f70334d4..ec34eddb6 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -133,14 +133,6 @@ extern Pixmap nxagentIconPixmap; extern Pixmap nxagentIconShape; extern Bool useXpmIcon; -/* - * From randr/randr.c. - */ - -extern Bool RRGetInfo(ScreenPtr pScreen); -extern void RRSendConfigNotify(ScreenPtr pScreen); -extern void RREditConnectionInfo(ScreenPtr pScreen); - Window nxagentDefaultWindows[MAXSCREENS]; Window nxagentInputWindows[MAXSCREENS]; Window nxagentScreenSaverWindows[MAXSCREENS]; @@ -323,7 +315,7 @@ void nxagentMaximizeToFullScreen(ScreenPtr pScreen) XUnmapWindow(nxagentDisplay, nxagentIconWindow); */ /* -FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWindow() +FIXME: We'll check for ReparentNotify and LeaveNotify events after XReparentWindow() in order to avoid the session window is iconified. We could avoid the sesssion window is iconified when a LeaveNotify event is received, so this check would be unnecessary. @@ -1121,6 +1113,9 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen, nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth)); nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight)); + /* store the user's preference provided via cmdline */ + nxagentOption(Xinerama) = !noPanoramiXExtension; + if (nxagentReconnectTrap == 0) { if (nxagentOption(Persistent)) @@ -2039,6 +2034,9 @@ N/A nxagentCompositeExtensionInit(); + /* We use this to get informed about RandR changes on the real display. + FIXME: It would probably be better to use an RRScreenChangeNotifyEvent here. */ + XSelectInput(nxagentDisplay, DefaultRootWindow(nxagentDisplay), StructureNotifyMask); #ifdef NXAGENT_TIMESTAMP @@ -2075,6 +2073,10 @@ Bool nxagentCloseScreen(int index, ScreenPtr pScreen) { int i; + #ifdef DEBUG + fprintf(stderr, "running nxagentCloseScreen()\n"); + #endif + for (i = 0; i < pScreen->numDepths; i++) { xfree(pScreen->allowedDepths[i].vids); @@ -3589,21 +3591,61 @@ Bool nxagentReconnectScreen(void *p0) return True; } -RRModePtr nxagentRRCustomMode = NULL; +/* FIXME: there must be such macros somewhere already...*/ +#define MAX(a,b) ((a) > (b)) ? (a) : (b); +#define MIN(a,b) ((a) < (b)) ? (a) : (b); + +/* intersect two rectangles */ +Bool intersect(int ax1, int ay1, unsigned int aw, unsigned int ah, + int bx1, int by1, unsigned int bw, unsigned int bh, + int *x, int *y, unsigned int *w, unsigned int *h) +{ + int tx1, ty1, tx2, ty2, ix, iy; + unsigned int iw, ih; + + int ax2 = ax1 + aw; + int ay2 = ay1 + ah; + int bx2 = bx1 + bw; + int by2 = by1 + bh; + + /* thanks to http://silentmatt.com/rectangle-intersection */ + + /* check if there's any intersection at all */ + if (ax2 < bx1 || bx2 < ax1 || ay2 < by1 || by2 < ay1) { + return FALSE; + } + + tx1 = MAX(ax1, bx1); + ty1 = MAX(ay1, by1); + tx2 = MIN(ax2, bx2); + ty2 = MIN(ay2, by2); + + ix = tx1 - ax1; + iy = ty1 - ay1; + iw = tx2 - tx1; + ih = ty2 - ty1; + + /* check if the resulting rectangle is feasible */ + if (iw <= 0 || ih <= 0) { + return FALSE; + } + *x = ix; + *y = iy; + *w = iw; + *h = ih; + return TRUE; +} int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, int mmHeight) { ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RROutputPtr output; - RRCrtcPtr crtc; - RRModePtr mode; - xRRModeInfo modeInfo; - char name[100]; - int r, c, m; - int refresh = 60; - int doNotify = 1; + /* FIXME: when is this needed? */ + int doNotify = TRUE; + int r; + #ifdef TEST + fprintf(stderr, "nxagentChangeScreenConfig: WindowTable[%d] is %p\n", screen, WindowTable[screen]); + #endif if (WindowTable[screen] == NULL) { return 0; @@ -3611,16 +3653,16 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in UpdateCurrentTime(); - if (nxagentGrabServerInfo.grabstate == SERVER_GRABBED) + if (nxagentGrabServerInfo.grabstate == SERVER_GRABBED && nxagentGrabServerInfo.client != NULL) { /* * If any client grabbed the server it won't expect that screen * configuration changes until it releases the grab. That could - * get an X error because available modes are chanded meanwhile. + * get an X error because available modes are changed meanwhile. */ #ifdef TEST - fprintf(stderr, "nxagentChangeScreenConfig: Cancel with grabbed server.\n"); + fprintf(stderr, "nxagentChangeScreenConfig: Cancel with grabbed server (grab held by %p).\n", nxagentGrabServerInfo.client); #endif return 0; @@ -3636,76 +3678,328 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in if (r != 0) { - pScrPriv = rrGetScrPriv(pScreen); + nxagentAdjustRandRXinerama(pScreen); + } + + if (doNotify) + { + RRScreenSizeNotify(pScreen); + } + +#ifdef DEBUG + fprintf(stderr, "nxagentChangeScreenConfig: Geometry: %d,%d %dx%d\n", nxagentOption(X), nxagentOption(Y),nxagentOption(Width),nxagentOption(Height)); + fprintf(stderr, "nxagentChangeScreenConfig: return %d\n", r); +#endif + + return r; +} - if (pScrPriv) +int nxagentAdjustRandRXinerama(ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + RROutputPtr output; + xRRModeInfo modeInfo; + char name[100]; + int refresh = 60; + int width = nxagentOption(Width); + int height = nxagentOption(Height); + + pScrPriv = rrGetScrPriv(pScreen); + + if (pScrPriv) + { + int i, j; + int number = 0; + + XineramaScreenInfo *screeninfo = NULL; + + if (nxagentOption(Xinerama)) { + screeninfo = XineramaQueryScreens(nxagentDisplay, &number); +#ifdef DEBUG + if (number) { + fprintf(stderr, "nxagentAdjustRandRXinerama: XineramaQueryScreens() returned %d screens\n", number); + } + else + { + fprintf(stderr, "nxagentAdjustRandRXinerama: XineramaQueryScreens() failed - continuing without xinerama\n"); + } + } + else + { + fprintf(stderr, "nxagentAdjustRandRXinerama: Xinerama is disabled\n"); +#endif + } + + /* + * if there's no xinerama on the real server or xinerama is + * disabled in nxagent we only report one big screen. Clients + * still see xinerama enabled but it will report only one (big) + * screen. This is consistent with the way rrxinerama always + * behaved. The single PanoramiX/Xinerama extension however + * disables xinerama if only one screen exists. + */ + if (number == 0) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: faking xinerama\n" ); + #endif + number = 1; + + if (screeninfo) { + xfree(screeninfo); + } + if (!(screeninfo = xalloc(sizeof(XineramaScreenInfo)))) { + return FALSE; + } + + /* fake a xinerama screeninfo that covers the whole screen */ + screeninfo->x_org = nxagentOption(X); + screeninfo->y_org = nxagentOption(Y); + screeninfo->width = nxagentOption(Width); + screeninfo->height = nxagentOption(Height); + } + +#ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs = %d, numOutputs = %d\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); { - output = RRFirstOutput(pScreen); + Bool rrgetinfo; - if (output && output -> crtc) + /* + * Convert old RANDR 1.0 data (if any) to current structure. This + * is needed once at the first run of this function. If we don't + * do this here it will be done implicitely later and add mode(s) to + * our crtc(s)! + */ + rrgetinfo = RRGetInfo(pScreen); + + fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned %d\n", rrgetinfo); + } +#else + /* we are not interested in the return code */ + RRGetInfo(pScreen); +#endif + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs = %d, numOutputs = %d\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); + #endif + + /* adjust the number of CRTCs to match the number of reported + xinerama screens on the real server */ + while (number != pScrPriv->numCrtcs) { + if (number < pScrPriv->numCrtcs) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying crtc\n"); + #endif + RRCrtcDestroy(pScrPriv->crtcs[pScrPriv->numCrtcs - 1]); + } + else { - crtc = output -> crtc; + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: adding crtc\n"); + #endif + RRCrtcCreate(pScreen, NULL); + } + } - for (c = 0; c < pScrPriv -> numCrtcs; c++) - { - RRCrtcSet(pScrPriv -> crtcs[c], NULL, 0, 0, RR_Rotate_0, 0, NULL); + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs = %d, numOutputs = %d\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); + #endif + + /* set gamma. Currently the only reason for doing this is + preventing the xrandr command from complaining about missing + gamma. */ + for (i = 0; i < pScrPriv->numCrtcs; i++) { + if (pScrPriv->crtcs[i]->gammaSize == 0) { + CARD16 gamma = 0; + RRCrtcGammaSetSize(pScrPriv->crtcs[i], 1); + RRCrtcGammaSet(pScrPriv->crtcs[i], &gamma, &gamma, &gamma); + RRCrtcGammaNotify(pScrPriv->crtcs[i]); + } + } + + /* delete superfluous non-NX outputs */ + for (i = pScrPriv->numOutputs - 1; i >= 0; i--) { + if (strncmp(pScrPriv->outputs[i]->name, "NX", 2)) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying output %s\n", pScrPriv->outputs[i]->name); + #endif + RROutputDestroy(pScrPriv->outputs[i]); + } + } + + /* at this stage only NX outputs are left - we delete the superfluous ones */ + for (i = pScrPriv->numOutputs - 1; i >= number; i--) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying output %s\n", pScrPriv->outputs[i]->name); + #endif + RROutputDestroy(pScrPriv->outputs[i]); + } + + /* add and init outputs */ + for (i = 0; i < number; i++) { + if (i >= pScrPriv->numOutputs) { + sprintf(name, "NX%d", i+1); + output = RROutputCreate(pScreen, name, strlen(name), NULL); + /* will be done later + RROutputSetConnection(output, RR_Disconnected); + */ + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: created new output %s\n", name); + #endif + } + else + { + output = pScrPriv->outputs[i]; + } + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: adjusting output %s\n", pScrPriv->outputs[i]->name); + #endif + RROutputSetCrtcs(output, &(pScrPriv->crtcs[i]), 1); + /* FIXME: Isn't there a function for setting this? */ + output->crtc = pScrPriv->crtcs[i]; + /* FIXME: get SubPixelOrder from real X server */ + RROutputSetSubpixelOrder(output, SubPixelUnknown); + /* FIXME: What is the correct physical size here? */ + RROutputSetPhysicalSize(output, 0, 0); + } + + for (i = 0; i < pScrPriv->numOutputs; i++ ) { + Bool disable_output = FALSE; + RRModePtr mymode, prevmode; + int new_x, new_y; + unsigned int new_w, new_h; + + /* if there's no intersection disconnect the output */ + disable_output = !intersect(nxagentOption(X), nxagentOption(Y), + width, height, + screeninfo[i].x_org, screeninfo[i].y_org, + screeninfo[i].width, screeninfo[i].height, + &new_x, &new_y, &new_w, &new_h); + + RROutputSetCrtcs(pScrPriv->outputs[i], &(pScrPriv->crtcs[i]), 1); + + /* save previous mode */ + prevmode = pScrPriv->crtcs[i]->mode; + + if (disable_output) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: no (valid) intersection - disconnecting\n", i); + #endif + RROutputSetConnection(pScrPriv->outputs[i], RR_Disconnected); + + /* + * Tests revealed that some window managers (e.g. LXDE) also + * take disconnected outputs into account when calculating + * stuff like wallpaper tile size and maximum window + * size. This is problematic when the disconnected output is + * smaller than any of the connected ones. Solution: unset + * the mode of the output's crtc. This also leads to + * xinerama not showing the disconnected head anymore. + */ + RRCrtcSet(pScrPriv->crtcs[i], NULL, 0, 0, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); + RROutputSetModes(pScrPriv->outputs[i], NULL, 0, 0); + if(prevmode) { + if(prevmode->refcnt == 1) + FreeResource(prevmode->mode.id, 0); } + } + else + { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: crtc %d: intersection is x=%d, y=%d, width=%d, height=%d'\n", i, new_x, new_y, new_w, new_h); + #endif + RROutputSetConnection(pScrPriv->outputs[i], RR_Connected); memset(&modeInfo, '\0', sizeof(modeInfo)); - sprintf(name, "%dx%d", width, height); - - modeInfo.width = width; - modeInfo.height = height; - modeInfo.hTotal = width; - modeInfo.vTotal = height; - modeInfo.dotClock = ((CARD32) width * (CARD32) height * - (CARD32) refresh); + /* avoid collisions with pre-existing default modes by using a + separate namespace. If we'd simply use XxY we could not + distinguish between pre-existing modes which should stay + and our own modes that should be removed after use. */ + /*sprintf(name, "nx%d", i+1);*/ + /*sprintf(name, "%dx%d", new_w, new_h);*/ + sprintf(name, "nx_%dx%d", new_w, new_h); + + modeInfo.width = new_w; + modeInfo.height = new_h; + modeInfo.hTotal = new_w; + modeInfo.vTotal = new_h; + modeInfo.dotClock = ((CARD32) new_w * (CARD32) new_h * (CARD32) refresh); modeInfo.nameLength = strlen(name); - if (nxagentRRCustomMode != NULL) + mymode = RRModeGet(&modeInfo, name); + +#ifdef DEBUG + if (mymode) { + fprintf(stderr, "nxagentAdjustRandRXinerama: mode %s (%p) created/received, refcnt=%d\n", name, mymode, mymode->refcnt); + } + else { - RROutputDeleteUserMode(output, nxagentRRCustomMode); - FreeResource(nxagentRRCustomMode -> mode.id, 0); + fprintf(stderr, "nxagentAdjustRandRXinerama: mode %s creation failed!\n", name); + } +#endif - if (crtc != NULL && crtc -> mode == nxagentRRCustomMode) + if (prevmode) { + if (mymode == prevmode) { - RRCrtcSet(crtc, NULL, 0, 0, RR_Rotate_0, 0, NULL); + /* if they are the same RRModeGet() has increased the + refcnt by 1. We decrease it again by calling only + RRModeDestroy() and forget about prevmode */ + } else { + RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0); + RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); } - - #ifdef TEST - fprintf(stderr, "nxagentChangeScreenConfig: " - "Going to destroy mode %p with refcnt %d.\n", - nxagentRRCustomMode, nxagentRRCustomMode->refcnt); - #endif - - RRModeDestroy(nxagentRRCustomMode); + if(prevmode->refcnt == 1) + FreeResource(prevmode->mode.id, 0); + } + else + { + /* we do not have a previous mode, so there's no need to handle it here */ + RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0); + RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); } - nxagentRRCustomMode = RRModeGet(&modeInfo, name); - - RROutputAddUserMode(output, nxagentRRCustomMode); + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: mode %s (%p) added to output and crtc %d\n", name, mymode, i); + #endif + } /* if disable_output */ - RRCrtcSet(crtc, nxagentRRCustomMode, 0, 0, RR_Rotate_0, 1, &output); + RROutputChanged(pScrPriv->outputs[i], TRUE); + RRCrtcChanged(pScrPriv->crtcs[i], TRUE); + } - RROutputChanged(output, 1); + /* release allocated memory */ + if (screeninfo) { + xfree(screeninfo); + screeninfo = NULL; + } - doNotify = 0; +#ifdef DEBUG + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRModePtr mode = pScrPriv->crtcs[i]->mode; + if (mode) { + fprintf(stderr, "nxagentAdjustRandRXinerama: crtc %d has mode %s and %d outputs\n", i, pScrPriv->crtcs[i]->mode->name, pScrPriv->crtcs[i]->numOutputs); + } + else + { + fprintf(stderr, "nxagentAdjustRandRXinerama: crtc %d has no mode and %d outputs\n", i, pScrPriv->crtcs[i]->numOutputs); } - pScrPriv -> lastSetTime = currentTime; - - pScrPriv->changed = 1; - pScrPriv->configChanged = 1; + fprintf(stderr, "nxagentAdjustRandRXinerama: output[%d]->crtc=%p\n", i, pScrPriv->outputs[i]->crtc); } +#endif - if (doNotify -) - { - RRScreenSizeNotify(pScreen); - } + pScrPriv -> lastSetTime = currentTime; + + pScrPriv->changed = TRUE; + pScrPriv->configChanged = TRUE; } - return r; + /* FIXME: adjust maximum screen size according to remote randr/xinerama setup */ + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: Min %dx%d, Max %dx%d \n", pScrPriv->minWidth,pScrPriv->minHeight,pScrPriv->maxWidth,pScrPriv->maxHeight); + #endif + + return TRUE; } void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, WindowPtr pWin) -- cgit v1.2.3 From 76a203410f19de13f8c1b34cabd08f70fa027995 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Tue, 6 Oct 2015 22:30:39 +0200 Subject: Screen.c: improve comments and DEBUG output --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 83 ++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 24 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index ec34eddb6..26971d025 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -3656,9 +3656,10 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in if (nxagentGrabServerInfo.grabstate == SERVER_GRABBED && nxagentGrabServerInfo.client != NULL) { /* - * If any client grabbed the server it won't expect that screen + * If any client grabbed the server it won't expect screen * configuration changes until it releases the grab. That could - * get an X error because available modes are changed meanwhile. + * lead to an X error because available modes are changed + * in the meantime. */ #ifdef TEST @@ -3721,7 +3722,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } else { - fprintf(stderr, "nxagentAdjustRandRXinerama: XineramaQueryScreens() failed - continuing without xinerama\n"); + fprintf(stderr, "nxagentAdjustRandRXinerama: XineramaQueryScreens() failed - continuing without Xinerama\n"); } } else @@ -3759,7 +3760,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs = %d, numOutputs = %d\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); + fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); { Bool rrgetinfo; @@ -3771,7 +3772,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) */ rrgetinfo = RRGetInfo(pScreen); - fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned %d\n", rrgetinfo); + fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned [%d]\n", rrgetinfo); } #else /* we are not interested in the return code */ @@ -3779,7 +3780,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) #endif #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs = %d, numOutputs = %d\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); + fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); #endif /* adjust the number of CRTCs to match the number of reported @@ -3801,7 +3802,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs = %d, numOutputs = %d\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); + fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); #endif /* set gamma. Currently the only reason for doing this is @@ -3820,7 +3821,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) for (i = pScrPriv->numOutputs - 1; i >= 0; i--) { if (strncmp(pScrPriv->outputs[i]->name, "NX", 2)) { #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: destroying output %s\n", pScrPriv->outputs[i]->name); + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying output [%s]\n", pScrPriv->outputs[i]->name); #endif RROutputDestroy(pScrPriv->outputs[i]); } @@ -3829,7 +3830,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) /* at this stage only NX outputs are left - we delete the superfluous ones */ for (i = pScrPriv->numOutputs - 1; i >= number; i--) { #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: destroying output %s\n", pScrPriv->outputs[i]->name); + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying output [%s]\n", pScrPriv->outputs[i]->name); #endif RROutputDestroy(pScrPriv->outputs[i]); } @@ -3843,7 +3844,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RROutputSetConnection(output, RR_Disconnected); */ #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: created new output %s\n", name); + fprintf(stderr, "nxagentAdjustRandRXinerama: created new output [%s]\n", name); #endif } else @@ -3851,7 +3852,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) output = pScrPriv->outputs[i]; } #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: adjusting output %s\n", pScrPriv->outputs[i]->name); + fprintf(stderr, "nxagentAdjustRandRXinerama: adjusting output [%s]\n", pScrPriv->outputs[i]->name); #endif RROutputSetCrtcs(output, &(pScrPriv->crtcs[i]), 1); /* FIXME: Isn't there a function for setting this? */ @@ -3875,10 +3876,18 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) screeninfo[i].width, screeninfo[i].height, &new_x, &new_y, &new_w, &new_h); - RROutputSetCrtcs(pScrPriv->outputs[i], &(pScrPriv->crtcs[i]), 1); - /* save previous mode */ prevmode = pScrPriv->crtcs[i]->mode; + #ifdef DEBUG + if (prevmode) { + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: prevmode [%s] ([%p]) refcnt [%d]\n", i, prevmode->name, prevmode, prevmode->refcnt); + } else { + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: no prevmode\n", i); + } + #endif + + RROutputSetCrtcs(pScrPriv->outputs[i], &(pScrPriv->crtcs[i]), 1); + if (disable_output) { #ifdef DEBUG @@ -3897,15 +3906,23 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) */ RRCrtcSet(pScrPriv->crtcs[i], NULL, 0, 0, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); RROutputSetModes(pScrPriv->outputs[i], NULL, 0, 0); - if(prevmode) { - if(prevmode->refcnt == 1) + + if (prevmode) { + /* throw away the previous mode, we do not need it + anymore. If refcnt is 1 we call FreeResource() to ensure + the system will not try to free it again on shutdown */ + + if (prevmode->refcnt == 1) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying prevmode [%s] ([%p])\n", prevmode->name, prevmode); + #endif FreeResource(prevmode->mode.id, 0); } } else { #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: crtc %d: intersection is x=%d, y=%d, width=%d, height=%d'\n", i, new_x, new_y, new_w, new_h); + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: intersection is x [%d] y [%d] width [%d] height [%d]\n", i, new_x, new_y, new_w, new_h); #endif RROutputSetConnection(pScrPriv->outputs[i], RR_Connected); @@ -3929,22 +3946,35 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) #ifdef DEBUG if (mymode) { - fprintf(stderr, "nxagentAdjustRandRXinerama: mode %s (%p) created/received, refcnt=%d\n", name, mymode, mymode->refcnt); + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: mode [%s] ([%p]) created/received, refcnt [%d]\n", i, name, mymode, mymode->refcnt); } else { - fprintf(stderr, "nxagentAdjustRandRXinerama: mode %s creation failed!\n", name); + /* FIXME: what is the correct behaviour in this case? */ + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: mode [%s] creation failed!\n", i, name); } #endif if (prevmode) { if (mymode == prevmode) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: mymode [%s] ([%p]) == prevmode [%s] ([%p])\n", mymode->name, mymode, prevmode->name, prevmode); + #endif + /* if they are the same RRModeGet() has increased the refcnt by 1. We decrease it again by calling only RRModeDestroy() and forget about prevmode */ } else { + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for output %d\n", mymode->name, mymode, mymode->refcnt, i); + #endif RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0); + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for crtc %d\n", mymode->name, mymode, mymode->refcnt, i); + #endif RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); } if(prevmode->refcnt == 1) @@ -3953,13 +3983,17 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) else { /* we do not have a previous mode, so there's no need to handle it here */ + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for output %d\n", mymode->name, mymode, mymode->refcnt, i); + #endif RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0); + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for crtc %d\n", mymode->name, mymode, mymode->refcnt, i); + #endif RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); } - - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: mode %s (%p) added to output and crtc %d\n", name, mymode, i); - #endif } /* if disable_output */ RROutputChanged(pScrPriv->outputs[i], TRUE); @@ -3976,14 +4010,15 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) for (i = 0; i < pScrPriv->numCrtcs; i++) { RRModePtr mode = pScrPriv->crtcs[i]->mode; if (mode) { - fprintf(stderr, "nxagentAdjustRandRXinerama: crtc %d has mode %s and %d outputs\n", i, pScrPriv->crtcs[i]->mode->name, pScrPriv->crtcs[i]->numOutputs); + fprintf(stderr, "nxagentAdjustRandRXinerama: crtc %d has mode [%s] ([%p]), refcnt [%d] and %d outputs\n", i, pScrPriv->crtcs[i]->mode->name, pScrPriv->crtcs[i]->mode, pScrPriv->crtcs[i]->mode->refcnt, pScrPriv->crtcs[i]->numOutputs); } else { fprintf(stderr, "nxagentAdjustRandRXinerama: crtc %d has no mode and %d outputs\n", i, pScrPriv->crtcs[i]->numOutputs); } - fprintf(stderr, "nxagentAdjustRandRXinerama: output[%d]->crtc=%p\n", i, pScrPriv->outputs[i]->crtc); + if (pScrPriv->crtcs[i]->numOutputs > 0) + fprintf(stderr, " output[%d]->crtc=[%p]\n", i, pScrPriv->outputs[i]->crtc); } #endif -- cgit v1.2.3 From 359f48dd7e036b5a009efe04033041bda8bd954f Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Tue, 6 Oct 2015 22:32:12 +0200 Subject: Screen.c: Fix freeing of unsued modes --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 37 ++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 26971d025..e844517bf 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -3904,10 +3904,17 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) * the mode of the output's crtc. This also leads to * xinerama not showing the disconnected head anymore. */ - RRCrtcSet(pScrPriv->crtcs[i], NULL, 0, 0, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); - RROutputSetModes(pScrPriv->outputs[i], NULL, 0, 0); - if (prevmode) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: removing mode from ctrc %d\n", i); + #endif + RRCrtcSet(pScrPriv->crtcs[i], NULL, 0, 0, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: removing mode from output %d\n", i); + #endif + RROutputSetModes(pScrPriv->outputs[i], NULL, 0, 0); + /* throw away the previous mode, we do not need it anymore. If refcnt is 1 we call FreeResource() to ensure the system will not try to free it again on shutdown */ @@ -3917,6 +3924,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) fprintf(stderr, "nxagentAdjustRandRXinerama: destroying prevmode [%s] ([%p])\n", prevmode->name, prevmode); #endif FreeResource(prevmode->mode.id, 0); + } } } else @@ -3932,8 +3940,8 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) distinguish between pre-existing modes which should stay and our own modes that should be removed after use. */ /*sprintf(name, "nx%d", i+1);*/ - /*sprintf(name, "%dx%d", new_w, new_h);*/ - sprintf(name, "nx_%dx%d", new_w, new_h); + sprintf(name, "%dx%d", new_w, new_h); + /*sprintf(name, "nx_%dx%d", new_w, new_h);*/ modeInfo.width = new_w; modeInfo.height = new_h; @@ -3954,7 +3962,6 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: mode [%s] creation failed!\n", i, name); } #endif - if (prevmode) { if (mymode == prevmode) { @@ -3965,6 +3972,8 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) /* if they are the same RRModeGet() has increased the refcnt by 1. We decrease it again by calling only RRModeDestroy() and forget about prevmode */ + RRModeDestroy(mymode); + } else { #ifdef DEBUG @@ -3976,9 +3985,18 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for crtc %d\n", mymode->name, mymode, mymode->refcnt, i); #endif RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); - } - if(prevmode->refcnt == 1) - FreeResource(prevmode->mode.id, 0); + + /* throw away the mode if otherwise unused. We do not need + it anymore. We call FreeResource() to ensure the system + will not try to free it again on shutdown */ + + if (prevmode->refcnt == 1) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying prevmode [%s]\n", prevmode->name); + #endif + FreeResource(prevmode->mode.id, 0); + } + } } else { @@ -3998,6 +4016,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RROutputChanged(pScrPriv->outputs[i], TRUE); RRCrtcChanged(pScrPriv->crtcs[i], TRUE); + } /* release allocated memory */ -- cgit v1.2.3 From 9b87a384e24a4b8873e0dc5853e6b573791f0d33 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Tue, 6 Oct 2015 22:53:16 +0200 Subject: Screen.c: restructure xinerama code, much shorter now --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 104 +++++++++++----------------- 1 file changed, 40 insertions(+), 64 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index e844517bf..4638b261c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -1780,7 +1780,9 @@ N/A XSetClassHint(nxagentDisplay,nxagentDefaultWindows[pScreen->myNum],&hint); free(hint.res_name); free(hint.res_class); - } else { + } + else + { #ifdef TEST fprintf(stderr, "nxagentOpenScreen: Setting WM_CLASS and WM_NAME for window withid [%ld].\n", nxagentDefaultWindows[pScreen->myNum]); @@ -2246,7 +2248,7 @@ static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable) if (pWin->realized) WindowsRestructured (); FlushAllOutput (); -} +} Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height, int mmWidth, int mmHeight) @@ -3888,7 +3890,6 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RROutputSetCrtcs(pScrPriv->outputs[i], &(pScrPriv->crtcs[i]), 1); - if (disable_output) { #ifdef DEBUG fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: no (valid) intersection - disconnecting\n", i); @@ -3899,32 +3900,21 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) * Tests revealed that some window managers (e.g. LXDE) also * take disconnected outputs into account when calculating * stuff like wallpaper tile size and maximum window - * size. This is problematic when the disconnected output is - * smaller than any of the connected ones. Solution: unset - * the mode of the output's crtc. This also leads to - * xinerama not showing the disconnected head anymore. + * size. This is problematic when a disconnected output is + * smaller than any of the connected ones. Solution: unset the + * mode of the output's crtc. This also leads to xinerama not + * showing the disconnected head anymore. */ if (prevmode) { - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: removing mode from ctrc %d\n", i); - #endif - RRCrtcSet(pScrPriv->crtcs[i], NULL, 0, 0, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); - #ifdef DEBUG fprintf(stderr, "nxagentAdjustRandRXinerama: removing mode from output %d\n", i); #endif RROutputSetModes(pScrPriv->outputs[i], NULL, 0, 0); - /* throw away the previous mode, we do not need it - anymore. If refcnt is 1 we call FreeResource() to ensure - the system will not try to free it again on shutdown */ - - if (prevmode->refcnt == 1) { - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: destroying prevmode [%s] ([%p])\n", prevmode->name, prevmode); - #endif - FreeResource(prevmode->mode.id, 0); - } + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: removing mode from ctrc %d\n", i); + #endif + RRCrtcSet(pScrPriv->crtcs[i], NULL, 0, 0, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); } } else @@ -3935,14 +3925,17 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RROutputSetConnection(pScrPriv->outputs[i], RR_Connected); memset(&modeInfo, '\0', sizeof(modeInfo)); + +#ifdef NX_USE_MODE_PREFIX /* avoid collisions with pre-existing default modes by using a separate namespace. If we'd simply use XxY we could not distinguish between pre-existing modes which should stay and our own modes that should be removed after use. */ + sprintf(name, "nx_%dx%d", new_w, new_h);*/ /*sprintf(name, "nx%d", i+1);*/ +#else sprintf(name, "%dx%d", new_w, new_h); - /*sprintf(name, "nx_%dx%d", new_w, new_h);*/ - +#endif modeInfo.width = new_w; modeInfo.height = new_h; modeInfo.hTotal = new_w; @@ -3958,50 +3951,22 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } else { - /* FIXME: what is the correct behaviour in this case? */ + /* FIXME: what is the correct behaviour in this case? */ fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: mode [%s] creation failed!\n", i, name); } #endif - if (prevmode) { - if (mymode == prevmode) - { - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: mymode [%s] ([%p]) == prevmode [%s] ([%p])\n", mymode->name, mymode, prevmode->name, prevmode); - #endif - - /* if they are the same RRModeGet() has increased the - refcnt by 1. We decrease it again by calling only - RRModeDestroy() and forget about prevmode */ - RRModeDestroy(mymode); - - } else { - - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for output %d\n", mymode->name, mymode, mymode->refcnt, i); - #endif - RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0); - - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for crtc %d\n", mymode->name, mymode, mymode->refcnt, i); - #endif - RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); - - /* throw away the mode if otherwise unused. We do not need - it anymore. We call FreeResource() to ensure the system - will not try to free it again on shutdown */ - - if (prevmode->refcnt == 1) { - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: destroying prevmode [%s]\n", prevmode->name); - #endif - FreeResource(prevmode->mode.id, 0); - } - } + if (prevmode && mymode == prevmode) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: mymode [%s] ([%p]) == prevmode [%s] ([%p])\n", mymode->name, mymode, prevmode->name, prevmode); + #endif + + /* if they are the same RRModeGet() has increased the + refcnt by 1. We decrease it again by calling only + RRModeDestroy() and forget about prevmode */ + RRModeDestroy(mymode); } else - { - /* we do not have a previous mode, so there's no need to handle it here */ - + { #ifdef DEBUG fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for output %d\n", mymode->name, mymode, mymode->refcnt, i); #endif @@ -4011,12 +3976,23 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for crtc %d\n", mymode->name, mymode, mymode->refcnt, i); #endif RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); + } } /* if disable_output */ + /* throw away the mode if otherwise unused. We do not need it + anymore. We call FreeResource() to ensure the system will not + try to free it again on shutdown */ + + if (prevmode && prevmode->refcnt == 1) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: destroying prevmode [%s]\n", prevmode->name); + #endif + FreeResource(prevmode->mode.id, 0); + } + RROutputChanged(pScrPriv->outputs[i], TRUE); RRCrtcChanged(pScrPriv->crtcs[i], TRUE); - } /* release allocated memory */ -- cgit v1.2.3 From f1eafeaa456b1544384bb6a68d8a56c0a216a875 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 7 Oct 2015 15:17:59 +0200 Subject: Screen.c: Rename NX_USE_MODE_PREFIX to NXAGENT_RANDR_MODE_PREFIX, fix unclosed comment. --- nx-X11/programs/Xserver/hw/nxagent/Imakefile | 2 ++ nx-X11/programs/Xserver/hw/nxagent/Screen.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile index 794864cf3..8cae91331 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile +++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile @@ -179,6 +179,7 @@ INCLUDES = -I. -I$(XBUILDINCDIR) \ # NXAGENT_CLIPBOARD Enables clipboard cut and paste function between X servers. # NXAGENT_FONTEXCLUDE Exclude some specific font names (only "-ult1mo" at this moment). # NXAGENT FULLSCREEN Fullscreen mode +# NXAGENT_RANDR_MODE_PREFIX Use prefixed (i.e., nx_x) RandR modes # #if nxVersion @@ -203,6 +204,7 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(NX_DEFINES) \ -DNXAGENT_ONSTART \ -DNXAGENT_SPLASH \ -DNXAGENT_ARTSD \ + -DNXAGENT_RANDR_MODE_PREFIX \ -UNX_DEBUG_INPUT \ -DRANDR_10_INTERFACE \ -DRANDR_12_INTERFACE \ diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 4638b261c..087f3f41a 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -3926,13 +3926,12 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) memset(&modeInfo, '\0', sizeof(modeInfo)); -#ifdef NX_USE_MODE_PREFIX +#ifdef NXAGENT_RANDR_MODE_PREFIX /* avoid collisions with pre-existing default modes by using a separate namespace. If we'd simply use XxY we could not distinguish between pre-existing modes which should stay and our own modes that should be removed after use. */ - sprintf(name, "nx_%dx%d", new_w, new_h);*/ - /*sprintf(name, "nx%d", i+1);*/ + sprintf(name, "nx_%dx%d", new_w, new_h); #else sprintf(name, "%dx%d", new_w, new_h); #endif -- cgit v1.2.3 From e7e2f164b9bcf05d4cc1eb0e69879addec718824 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 7 Oct 2015 17:23:13 +0200 Subject: Only declare nxagentRandRCrtcSet if RANDR_12_INTERFACE is defined. --- nx-X11/programs/Xserver/hw/nxagent/Extensions.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c index 103eaa92c..d77d27674 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c @@ -35,10 +35,12 @@ static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, static int nxagentRandRInitSizes(ScreenPtr pScreen); +#if RANDR_12_INTERFACE static Bool nxagentRandRCrtcSet (ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode, int x, int y, Rotation rotation, int numOutputs, RROutputPtr *outputs); +#endif #ifdef __DARWIN__ -- cgit v1.2.3 From f40792c436c2e0678f46478002830367b683f20c Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 7 Oct 2015 17:24:01 +0200 Subject: Initialize XRandR based Xinerama extension properly when session is started with "-geometry fullscreen". --- nx-X11/programs/Xserver/hw/nxagent/Events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c index 03b14f0dc..c04481c92 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Events.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c @@ -3485,7 +3485,7 @@ int nxagentHandleConfigureNotify(XEvent* X) } else { - if (X -> xconfigure.window == DefaultRootWindow(nxagentDisplay)) + if ( (X -> xconfigure.window == DefaultRootWindow(nxagentDisplay)) || nxagentFullscreenWindow ) { #ifdef TEST fprintf(stderr, "nxagentHandleConfigureNotify: remote root window has changed: %d,%d %dx%d\n", X -> xconfigure.x, X -> xconfigure.y, X -> xconfigure.width, X -> xconfigure.height); -- cgit v1.2.3 From 0297567cd501b6fc012c41ff4a1ae27304ff6a10 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 7 Oct 2015 20:51:12 +0200 Subject: Provide support for re-enabling Xinerama on session resumptions. By design, when resuming a session, Xinerama can only be re-enabled by NX option parsing. Thus, this change introduces a "xinerama" NX option that can be loaded via an options file into NX agent when resuming a session. The new xinerame NX session option also allows switching on Xinerama at session startup via an option file. When implementing the new NX Xinerama support into clients (like TheQVD, X2Go Client, etc., this new xinerama NX option should be used for activating Xinerama in the NX / QVD / X2Go session. --- nx-X11/programs/Xserver/hw/nxagent/Args.c | 31 ++++++++++++++++++++++++++ nx-X11/programs/Xserver/hw/nxagent/Reconnect.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 6 +++-- 3 files changed, 36 insertions(+), 3 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c index 5c5a1e8f8..309f08d0e 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Args.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c @@ -42,6 +42,7 @@ is" without express or implied warranty. #include "screenint.h" #include "input.h" #include "misc.h" +#include "globals.h" #include "scrnintstr.h" #include "dixstruct.h" #include "servermd.h" @@ -1202,6 +1203,36 @@ static void nxagentParseOptions(char *name, char *value) return; } + else if (!strcmp(name, "xinerama")) + { +#ifdef PANORAMIX + if (!PanoramiXExtensionDisabledHack) + { + if (!strcmp(value, "1")) + { + nxagentChangeOption(Xinerama, 1); + } + else if (!strcmp(value, "0")) + { + nxagentChangeOption(Xinerama, 0); + } + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'xinerama'.\n", + validateString(value)); + } + } + else + { + nxagentChangeOption(Xinerama, 0); + fprintf(stderr, "Warning: Xinerama extension has been disabled via -disablexineramaextension cmdline switch.\n"); + } +#else + nxagentChangeOption(Xinerama, 0); + fprintf(stderr, "Warning: No Xinerama support compiled into nxagent.\n") +#endif /* of PANORAMIX */ + return; + } else if (!strcmp(name, "resize")) { if (nxagentOption(DesktopResize) == 0 || strcmp(value, "0") == 0) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c index b26fa9cfe..660d30863 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c @@ -624,7 +624,7 @@ Bool nxagentReconnectSession(void) nxagentRedirectDefaultWindows(); - if (nxagentResizeDesktopAtStartup || nxagentOption(Rootless) == True) + if (nxagentResizeDesktopAtStartup || nxagentOption(Rootless) == True || nxagentOption(Xinerama) == True) { nxagentChangeScreenConfig(0, nxagentOption(RootWidth), nxagentOption(RootHeight), 0, 0); diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 087f3f41a..17e749a6b 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -1113,8 +1113,10 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen, nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth)); nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight)); - /* store the user's preference provided via cmdline */ - nxagentOption(Xinerama) = !noPanoramiXExtension; + /* PanoramiXExtension enabled via cmdline, turn on Xinerama in nxagent + */ + if( (!noPanoramiXExtension) && (!PanoramiXExtensionDisabledHack) ) + nxagentOption(Xinerama) = True; if (nxagentReconnectTrap == 0) { -- cgit v1.2.3 From c4a388937baad8215f2650d746d3ddba4d4d1ee3 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Oct 2015 22:25:09 +0200 Subject: Xinerama: do not cut off at outer edges This fixes the problem Mike Gabriel describes like this: - Launch a session on a system with a single monitor. Enable Xinerama for this session. - Open a desktop session in that session window (e.g. MATE or XFCE). - Move the NX/MATE-or-XFCE session window around on that one monitor. Bump at the borders, so that the session window moves into the invisible parts around your monitor. What you see is that the MATE-or-XFCE window manager will become really busy with resizing the windows and panels in the NX session, because moving the window over the physical borders of the display will trigger resize events. This is non-intuitive, I think. Same with multi-monitors on the outside edges of the physical Xorg RandR setup. --- nx-X11/programs/Xserver/hw/nxagent/Imakefile | 2 +- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 78 +++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile index 8cae91331..160d01e60 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile +++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile @@ -180,7 +180,7 @@ INCLUDES = -I. -I$(XBUILDINCDIR) \ # NXAGENT_FONTEXCLUDE Exclude some specific font names (only "-ult1mo" at this moment). # NXAGENT FULLSCREEN Fullscreen mode # NXAGENT_RANDR_MODE_PREFIX Use prefixed (i.e., nx_x) RandR modes -# +# NXAGENT_RANDR_XINERAMA_CLIPPING cut off invisible window parts in xinerama mode (you probably do not want this) #if nxVersion NX_DEFINES=-DNX_VERSION_CURRENT="$(NX_VERSION_CURRENT)" \ diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 17e749a6b..a677b7eb4 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -106,8 +106,8 @@ is" without express or implied warranty. #define PANIC #define WARNING -#undef TEST -#undef DEBUG +#define TEST +#define DEBUG #undef WATCH #undef DUMP @@ -3640,6 +3640,36 @@ Bool intersect(int ax1, int ay1, unsigned int aw, unsigned int ah, return TRUE; } +#ifndef NXAGENT_RANDR_XINERAMA_CLIPPING +/* intersect two rectangles, return aw/ah for w/h if resulting + rectangle is (partly) outside of bounding box */ +Bool intersect_bb(int ax1, int ay1, unsigned int aw, unsigned int ah, + int bx1, int by1, unsigned int bw, unsigned int bh, + int bbx1, int bby1, int bbx2, int bby2, + int *x, int *y, unsigned int *w, unsigned int *h) +{ + Bool result = intersect(ax1, ay1, aw, ah, bx1, by1, bw, bh, x, y, w, h); + if (result == TRUE) { + /* check if outside of bounding box */ + if (ax1 < bbx1 || ax1 + aw > bbx2) { + #ifdef DEBUG + fprintf(stderr, "intersect: box has parts outside bounding box - width stays unchanged [%d]\n", aw); + #endif + *w = aw; + } + + if (ay1 < bby1 || ay1 + ah > bby2) { + #ifdef DEBUG + fprintf(stderr, "intersect: box has parts outside bounding box - height stays unchanged [%d]\n", ah); + #endif + *h = ah; + } + } + + return result; +} +#endif + int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, int mmHeight) { ScreenPtr pScreen; @@ -3783,6 +3813,23 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RRGetInfo(pScreen); #endif +#ifndef NXAGENT_RANDR_XINERAMA_CLIPPING + /* calculate bounding box (outer edges) */ + int bbx2, bbx1, bby1, bby2; + bbx2 = bby2 = 0; + bbx1 = bby1 = INT_MAX; + + for (i = 0; i < number; i++) { + bbx2 = MAX(bbx2, screeninfo[i].x_org + screeninfo[i].width); + bby2 = MAX(bby2, screeninfo[i].y_org + screeninfo[i].height); + bbx1 = MIN(bbx1, screeninfo[i].x_org); + bby1 = MIN(bby1, screeninfo[i].y_org); + } + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: bounding box: left [%d] right [%d] top [%d] bottom[%d]\n", bbx1, bbx2, bby1, bby2); + #endif +#endif + #ifdef DEBUG fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs); #endif @@ -3873,12 +3920,37 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) int new_x, new_y; unsigned int new_w, new_h; + /* + if ((nxagentOption(X) < bbx1 || (nxagentOption(X) + width >= bbx2 )) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: window has parts outside visible area - width stays unchanged [%d]\n", width); + #endif + new_w = width; + } + + if ((nxagentOption(Y) < bby1 || (nxagentOption(Y) + height >= bby2 ) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: window has parts outside visible area - height stays unchanged [%d]\n", height); + #endif + new_h = height; + } + */ + /* if there's no intersection disconnect the output */ +#ifdef NXAGENT_RANDR_XINERAMA_CLIPPING disable_output = !intersect(nxagentOption(X), nxagentOption(Y), width, height, screeninfo[i].x_org, screeninfo[i].y_org, screeninfo[i].width, screeninfo[i].height, &new_x, &new_y, &new_w, &new_h); +#else + disable_output = !intersect_bb(nxagentOption(X), nxagentOption(Y), + width, height, + screeninfo[i].x_org, screeninfo[i].y_org, + screeninfo[i].width, screeninfo[i].height, + bbx1, bby1, bbx2, bby2, + &new_x, &new_y, &new_w, &new_h); +#endif /* save previous mode */ prevmode = pScrPriv->crtcs[i]->mode; @@ -3924,6 +3996,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) #ifdef DEBUG fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: intersection is x [%d] y [%d] width [%d] height [%d]\n", i, new_x, new_y, new_w, new_h); #endif + RROutputSetConnection(pScrPriv->outputs[i], RR_Connected); memset(&modeInfo, '\0', sizeof(modeInfo)); @@ -3937,6 +4010,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) #else sprintf(name, "%dx%d", new_w, new_h); #endif + modeInfo.width = new_w; modeInfo.height = new_h; modeInfo.hTotal = new_w; -- cgit v1.2.3