From 184c07e24a3daa28ce3882ad72ce64c52716f72c Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Wed, 8 Feb 2017 21:13:38 +0100 Subject: Screen.c: Ensure that an output is unused before destroying it Fixes ArcticaProject/nx-libs#293 --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 42 +++++++++++++++++++---------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 0e0cd0b21..2f6381696 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -3741,6 +3741,27 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in return r; } +/* + Destroy an output after removing it from any crtc that might reference it + */ +void nxagentDropOutput(RROutputPtr o) { + RRCrtcPtr c = o->crtc; + if (c) { + for (int i = 0; i < c->numOutputs; i++) { + if (c->outputs[i] == o) { +#ifdef DEBUG + fprintf(stderr, "nxagentDropOutput: output [%s] is in use by crtc [%p], removing it from there\n", o->name, c); +#endif + RRCrtcSet(c, NULL, 0, 0, RR_Rotate_0, 0, NULL); + } + } + } +#ifdef DEBUG + fprintf(stderr, "nxagentDropOutput: destroying output [%s]\n", o->name); +#endif + RROutputDestroy(o); +} + int nxagentAdjustRandRXinerama(ScreenPtr pScreen) { rrScrPrivPtr pScrPriv; @@ -3858,6 +3879,8 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) #ifdef DEBUG fprintf(stderr, "nxagentAdjustRandRXinerama: destroying crtc\n"); #endif + /* first reset the crtc to free possible outputs, then destroy the crtc */ + RRCrtcSet(pScrPriv->crtcs[pScrPriv->numCrtcs - 1], NULL, 0, 0, RR_Rotate_0, 0, NULL); RRCrtcDestroy(pScrPriv->crtcs[pScrPriv->numCrtcs - 1]); } else @@ -3886,22 +3909,13 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } /* 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]); - } - } + for (i = pScrPriv->numOutputs - 1; i >= 0; i--) + if (strncmp(pScrPriv->outputs[i]->name, "NX", 2)) + nxagentDropOutput(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 nx output [%s]\n", pScrPriv->outputs[i]->name); - #endif - RROutputDestroy(pScrPriv->outputs[i]); - } + for (i = pScrPriv->numOutputs - 1; i >= number; i--) + nxagentDropOutput(pScrPriv->outputs[i]); /* add and init outputs */ for (i = 0; i < number; i++) { -- cgit v1.2.3 From 3790a28feccb4f1a235d880674f98dc89d15691e Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Wed, 8 Feb 2017 21:43:45 +0100 Subject: Screen.c: clean up superfluous whitespace --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 2f6381696..3039f4139 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -3812,7 +3812,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) */ if (number == 0) { #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: faking xinerama\n" ); + fprintf(stderr, "nxagentAdjustRandRXinerama: faking xinerama\n"); #endif number = 1; @@ -3934,7 +3934,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? */ @@ -3945,7 +3945,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RROutputSetPhysicalSize(output, 0, 0); } - for (i = 0; i < pScrPriv->numOutputs; i++ ) { + for (i = 0; i < pScrPriv->numOutputs; i++) { Bool disable_output = FALSE; RRModePtr mymode, prevmode; int new_x, new_y; @@ -4089,7 +4089,6 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) /* 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); -- cgit v1.2.3