This is an automated email from the git hooks/post-receive script. x2go pushed a change to branch 3.6.x-rpm-debug in repository nx-libs. from 9b63cf8 Merge branch 'bugfix/xinerama-crtcs' into 3.6.x-rpm-debug new 1e258b9 nx-X11/programs/Xserver/hw/nxagent/Screen.c: add high-level wrapper to generate and select a solution for a given base screen boxes list and remote Xinerama information. new f492689 nx-X11/programs/Xserver/hw/nxagent/Screen.c: reimplement Xinerama RandR adjustment function based on the new screen tiling functions. new 6e48683 nx-X11/programs/Xserver/hw/nxagent/Screen.c: remove obsolete intersect_bb() function. new db0a00a nx-X11/programs/Xserver/hw/nxagent/Imakefile: remove obsolete NXAGENT_RANDR_XINERAMA_CLIPPING macro. new b96fc6c Merge branch 'bugfix/xinerama-crtcs' into 3.6.x-rpm-debug The 5 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Summary of changes: nx-X11/programs/Xserver/hw/nxagent/Screen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch 3.6.x-rpm-debug in repository nx-libs. commit 1e258b91cb14a358a2ae9ecf55b26f5e816ad955 Author: Mihai Moldovan <ionic@ionic.de> Date: Tue Apr 24 14:58:55 2018 +0200 nx-X11/programs/Xserver/hw/nxagent/Screen.c: add high-level wrapper to generate and select a solution for a given base screen boxes list and remote Xinerama information. --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 167 ++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index bf82ca1..b28ab98 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -6575,6 +6575,173 @@ static nxagentScreenCrtcsSolutions* nxagentScreenCrtcsGenerateSolutions(const nx ret = best_ret; + return(ret); +} + +/* + * High-level wrapper generating a screen partition solution based upon a list + * of base boxes and the remote Xinerama screen information. + * + * No pointers might be NULL. screen_count might not be zero. + * + * On success, returns one specific screen partition solution, otherwise NULL. + */ +static nxagentScreenCrtcsSolution* nxagentMergeScreenCrtcs(nxagentScreenBoxes *boxes, const XineramaScreenInfo *screen_info, const size_t screen_count) { + nxagentScreenCrtcsSolution *ret = NULL; + + if ((!(boxes)) || (!(screen_info)) || (!(screen_count))) { + return(ret); + } + + size_t boxes_count = 0; + nxagentScreenBoxesElem *cur = NULL; + xorg_list_for_each_entry(cur, &(boxes->head), entry) { + ++boxes_count; + } + + /* + * Step 1: consolidate boxes. + * + * Boxes might intersect with one screen, multiple screens or no screen. + * We will consolidate boxes on a per-screen basis, in a way such that each + * box will not be next to another that intersects the same screens. + * Overlapping screens are handled by leaving a box in place if intersected + * by multiple screens, if its neighbors are not also intersected by the + * same screens. + * + * Example: + * + * ┌─────┬──────┬─────┬─────┐ + * │ 1 │ 1,2 │ 2 │ │ + * ├─────┼──────┼─────┼─────┤ + * │ 1 │ 1 │ │ │ + * └─────┴──────┴─────┴─────┘ + * + * Will/should be merged to: + * + * ┌─────┬──────┬─────┬─────┐ + * │ 1 │ 1,2 │ 2 │ │ + * │ └──────┼─────┼─────┤ + * │ 1 1 │ │ │ + * └────────────┴─────┴─────┘ + * + * I.e., after the operation, these boxes will/should exist: + * + * ┌────────────┐ ┌────────────┐ + * │ 1 │ │ 2 │ + * │ │ └────────────┘ + * └────────────┘ + */ + + nxagentScreenBoxes *screen_boxes = calloc(screen_count, sizeof(nxagentScreenBoxes)); + + if (!(screen_boxes)) { + nxagentFreeScreenBoxes(boxes, TRUE); + + return(ret); + } + + for (size_t i = 0; i < screen_count; ++i) { + xorg_list_init(&((screen_boxes + i)->head)); + } + + nxagentScreenBoxes *initial_screens = calloc(1, sizeof(nxagentScreenBoxes)); + + if (!(initial_screens)) { + nxagentFreeScreenBoxes(boxes, TRUE); + + return(ret); + } + + xorg_list_init(&(initial_screens->head)); + initial_screens->screen_id = -1; + + if (!(nxagentMergeScreenBoxes(boxes, screen_boxes, screen_info, screen_count))) { + for (size_t i = 0; i < screen_count; ++i) { + nxagentFreeScreenBoxes((screen_boxes + i), TRUE); + } + + SAFE_FREE(screen_boxes); + + nxagentFreeScreenBoxes(boxes, TRUE); + + return(ret); + } + + /* Step 2: merge screen boxes into initial_screens. */ + for (size_t i = 0; i < screen_count; ++i) { + /* Filter out boxes with no intersections. */ + if (!(xorg_list_is_empty(&((screen_boxes) + i)->head))) { + /* If merging was successful, we should only have one box per list. */ + nxagentScreenBoxesElem *cur = xorg_list_first_entry(&((screen_boxes + i)->head), nxagentScreenBoxesElem, entry); + + /* Remove from old list. */ + xorg_list_del(&(cur->entry)); + + /* Add to the other list. */ + xorg_list_append(&(cur->entry), &(initial_screens->head)); + +#ifdef WARNING + if (i != cur->screen_id) { + const unsigned long long idx = i; + const signed long long screen_id = cur->screen_id; + fprintf(stderr, "%s: internal screen id %lld doesn't match expected screen id %llu! Algorithm warning.\n", __func__, screen_id, idx); + } +#endif + } + } + + /* Lists should be all empty now, get rid of list heads. */ + SAFE_FREE(screen_boxes); + + /* Step 3: extend original screen boxes to cover the whole area. */ + nxagentScreenCrtcsSolutions *solutions = nxagentScreenCrtcsGenerateSolutions(boxes, initial_screens, boxes_count, screen_count, NULL); + + /* + * Everything should be copied internally, so get rid of our original data. + */ + nxagentFreeScreenBoxes(initial_screens, TRUE); + + SAFE_FREE(initial_screens); + + if ((!(solutions)) || (xorg_list_is_empty(solutions))) { + /* + * Invalid or empty solutions list means that something is wrong. + * Error out. + */ +#ifdef WARNING + fprintf(stderr, "%s: solutions list empty or invalid. Algorithm error.\n", __func__); +#endif + + nxagentScreenCrtcsFreeSolutions(solutions); + + SAFE_FREE(solutions); + + return(ret); + } + + /* + * Step 4: select specific solution. + * Should be valid, checked for emptiness before. It's possible to have + * multiple solutions (logically with the same rating), but we have to select + * a specific one here. + * We'll use the very first one. + */ + nxagentScreenCrtcsSolution *first_entry = xorg_list_first_entry(solutions, nxagentScreenCrtcsSolution, entry); + + ret = nxagentScreenCrtcsSolutionCopy(first_entry); + + nxagentScreenCrtcsFreeSolutions(solutions); + + SAFE_FREE(solutions); + + if (!(ret)) { +#ifdef WARNING + fprintf(stderr, "%s: unable to copy first solution entry.\n", __func__); +#endif + + return(ret); + } return(ret); } -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch 3.6.x-rpm-debug in repository nx-libs. commit f49268956def41e3d9153d20c89384b8bf023e27 Author: Mihai Moldovan <ionic@ionic.de> Date: Mon Apr 30 21:41:45 2018 +0200 nx-X11/programs/Xserver/hw/nxagent/Screen.c: reimplement Xinerama RandR adjustment function based on the new screen tiling functions. --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 533 +++++++++++++++++++++------- 1 file changed, 402 insertions(+), 131 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index b28ab98..5f3ac1d 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -45,6 +45,7 @@ is" without express or implied warranty. #include <stdarg.h> #include <math.h> #include <float.h> +#include <time.h> #include "scrnintstr.h" #include "dix.h" @@ -3988,6 +3989,8 @@ typedef struct { typedef struct xorg_list nxagentScreenCrtcsSolutions; +static nxagentScreenCrtcsSolution *nxagentScreenCrtcsTiling = NULL; + /* * Helper function that takes a potential split point, the window bounds, * a split count and a splits array. @@ -6767,6 +6770,240 @@ void nxagentDropOutput(RROutputPtr o) { RROutputDestroy(o); } +/* + * Helper used to swap the *data* of two nxagentScreenBoxesElem objects. + * Metadata, such as the internal list pointers, is not touched. + * + * Returns true on success, otherwise false. + */ +static Bool nxagentScreenBoxesElemSwap(nxagentScreenBoxesElem *lhs, nxagentScreenBoxesElem *rhs) { + Bool ret = FALSE; + + if ((!(lhs)) || (!(rhs))) { + return(ret); + } + + nxagentScreenBoxesElem *tmp = nxagentScreenBoxesElemCopy(lhs, FALSE); + + if (!(tmp)) { + return(ret); + } + + lhs->obsolete = rhs->obsolete; + lhs->screen_id = rhs->screen_id; + lhs->box = rhs->box; + + rhs->obsolete = tmp->obsolete; + rhs->screen_id = tmp->screen_id; + rhs->box = tmp->box; + + SAFE_FREE(tmp); + + ret = TRUE; + + return(ret); +} + +/* + * Helper executing the actual quicksort implementation. + * + * No pointer parameters might be NULL. + * + * Returns true on success, otherwise false. + */ +static Bool nxagentScreenBoxesQSortImpl(nxagentScreenBoxesElem *left, nxagentScreenBoxesElem *right, const size_t left_idx, const size_t right_idx, nxagentScreenBoxes *boxes) { + Bool ret = TRUE; + + if ((!(left)) || (!(right)) || (!(boxes))) { + ret = FALSE; + + return(ret); + } + + if (left_idx >= right_idx) { + return(ret); + } + + /* Select pivot. */ + size_t diff = (right_idx - left_idx); + size_t pivot_i = (left_idx + (rand() % diff)); + + nxagentScreenBoxesElem *pivot = NULL; + { + size_t i = 0; + xorg_list_for_each_entry(pivot, &(boxes->head), entry) { + if (i++ == pivot_i) { + break; + } + } + } + + /* IDs should be unique, so no need to optimize for same values. */ + nxagentScreenBoxesElem *left_ = left, + *right_ = right, + *split = NULL; + ssize_t left_i = left_idx, + right_i = right_idx, + split_i = -1; + while (TRUE) { + /* + * Careful: xorg_list_for_each_entry() skips over the first element (since + * it's assumed to be the list head without actual data), so we'll need to + * "rewind" the pointer first. + * + * Don't do this for right_, since we use a special implementation for + * iterating backwards. + */ + left_ = xorg_list_last_entry(&(left_->entry), nxagentScreenBoxesElem, entry); + + xorg_list_for_each_entry(left_, &(left_->entry), entry) { + if (&(left_->entry) == &(boxes->head)) { + ret = FALSE; + + break; + } + + /* + * Normally implementations check if they should continue, we check if we + * should break out instead. + * + * N.B.: left_ should never reach the list head. + */ + if ((left_->screen_id) >= (pivot->screen_id)) { + break; + } + + ++left_i; + } + + if (!(ret)) { + break; + } + + /* + * The xorg_list implementation does not have a way to iterate over a list + * reversely, so implement it with basic building blocks. + */ + while (&(right_->entry) != &(right->entry)) { + if (&(right_->entry) == &(boxes->head)) { + ret = FALSE; + + break; + } + + /* + * Normally implementations check if they should continue, we check if we + * should break out instead. + * + * N.B.: right_ should never reach the list head. + */ + if ((right_->screen_id) <= (pivot->screen_id)) { + break; + } + + --right_i; + + /* + * Move backwards. Last entry is actually the previous one. For more + * information see the comments in nxagentScreenBoxesUpdateScreenBox(). + */ + right_ = xorg_list_last_entry(&(right_->entry), nxagentScreenBoxesElem, entry); + } + + if (!(ret)) { + break; + } + + if (left_i >= right_i) { + split = right; + split_i = right_i; + + break; + } + + ret = nxagentScreenBoxesElemSwap(left_, right_); + + if (!(ret)) { + break; + } + } + + if (!(ret)) { + return(ret); + } + + ret = nxagentScreenBoxesQSortImpl(left, split, left_idx, split_i, boxes); + + if (!(ret)) { + return(ret); + } + + ret = nxagentScreenBoxesQSortImpl(xorg_list_first_entry(&(split->entry), nxagentScreenBoxesElem, entry), right, (split_i + 1), right_idx, boxes); + + return(ret); +} + +/* + * Helper sorting an nxagentScreenBoxes list. + * + * No pointer parameters might be NULL. + * + * Returns true on success, otherwise false. + */ +static Bool nxagentScreenBoxesQSort(nxagentScreenBoxes *boxes) { + Bool ret = FALSE; + + if (!(boxes)) { + return(ret); + } + + if (xorg_list_is_empty(&(boxes->head))) { + ret = TRUE; + + return(ret); + } + + /* + * Questionable optimization: check if list is already sorted. + */ + Bool sorted = TRUE; + { + ssize_t last_screen_id = -1; + nxagentScreenBoxesElem *cur = NULL; + xorg_list_for_each_entry(cur, &(boxes->head), entry) { + if (cur->screen_id < last_screen_id) { + sorted = FALSE; + + break; + } + + last_screen_id = cur->screen_id; + } + } + + if (sorted) { + ret = TRUE; + + return(ret); + } + + /* Seed PRNG. We don't need good entropy, some is enough. */ + srand((unsigned int)(time(NULL))); + + /* Get boxes count. */ + size_t boxes_count = 0; + { + nxagentScreenBoxesElem *cur = NULL; + xorg_list_for_each_entry(cur, &(boxes->head), entry) { + ++boxes_count; + } + } + + ret = nxagentScreenBoxesQSortImpl(xorg_list_first_entry(&(boxes->head), nxagentScreenBoxesElem, entry), xorg_list_last_entry(&(boxes->head), nxagentScreenBoxesElem, entry), 0, (boxes_count - 1), boxes); + + return(ret); +} + int nxagentAdjustRandRXinerama(ScreenPtr pScreen) { rrScrPrivPtr pScrPriv; @@ -6774,8 +7011,6 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) xRRModeInfo modeInfo; char name[100]; int refresh = 60; - int width = nxagentOption(Width); - int height = nxagentOption(Height); pScrPriv = rrGetScrPriv(pScreen); @@ -6801,7 +7036,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } /* - * if there's no xinerama on the real server or xinerama is + * 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 @@ -6848,33 +7083,102 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RRGetInfo(pScreen, FALSE); #endif -#ifndef NXAGENT_RANDR_XINERAMA_CLIPPING - /* calculate bounding box (outer edges) */ - int bbx2, bbx1, bby1, bby2; - bbx2 = bby2 = 0; - bbx1 = bby1 = INT_MAX; + nxagentScreenSplits *splits = nxagentGenerateScreenSplitList(screeninfo, number); + + if (!(splits)) { + fprintf(stderr, "%s: unable to generate screen split list.\n", __func__); - 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); + return(FALSE); + } + + nxagentScreenBoxes *all_boxes = nxagentGenerateScreenCrtcs(splits); + + /* Get rid of splits. */ + SAFE_FREE(splits->x_splits); + SAFE_FREE(splits->y_splits); + SAFE_FREE(splits); + + if ((!(all_boxes)) || xorg_list_is_empty(&(all_boxes->head))) { + fprintf(stderr, "%s: unable to generate screen boxes list from screen splitting list.\n", __func__); + + return(FALSE); + } + + nxagentScreenCrtcsSolution *solution = nxagentMergeScreenCrtcs(all_boxes, screeninfo, number); + + /* Get rid of all_boxes. */ + nxagentFreeScreenBoxes(all_boxes, TRUE); + + SAFE_FREE(all_boxes); + + if (!(solution)) { + fprintf(stderr, "%s: unable to extract screen boxes from screen metadata.\n", __func__); + + return(FALSE); + } + + /* Sort new solution boxes list based on screen ID. */ + Bool sorted = nxagentScreenBoxesQSort(solution->solution_boxes); + + if (!(sorted)) { + fprintf(stderr, "%s: unable to sort solution screen boxes based on screen IDs.\n", __func__); + + nxagentScreenCrtcsFreeSolution(solution); + + SAFE_FREE(solution); + + return(FALSE); } - #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 + #ifdef WARNING + if (nxagentScreenCrtcsTiling) { + size_t old_screen_count = 0; + nxagentScreenBoxesElem *cur = NULL; + xorg_list_for_each_entry(cur, &(nxagentScreenCrtcsTiling->solution_boxes->head), entry) { + ++old_screen_count; + } + + if (old_screen_count != pScrPriv->numCrtcs) { + const unsigned long long old_screen_count_ = old_screen_count; + const signed long long cur_crtcs_count = pScrPriv->numCrtcs; + fprintf(stderr, "%s: current CRTCs count [%lld] doesn't match old tiling data [%llu]. Algorithm warning.\n", __func__, cur_crtcs_count, old_screen_count_); + } + } + #endif + + size_t new_crtcs_count = 0; + { + nxagentScreenBoxesElem *cur = NULL; + xorg_list_for_each_entry(cur, &(solution->solution_boxes->head), entry) { + ++new_crtcs_count; + } + } + + /* + * Adjust the number of CRTCs to match the number of reported Xinerama + * screens on the real server that intersect the nxagent window. + */ /* - * adjust the number of CRTCs to match the number of reported - * xinerama screens on the real server + * The number of CRTCs might not be an appropriate means of setting up + * screen splitting since old and new screen IDs might differ. Doing some + * more complicated mapping between old and new screen IDs here would be + * possible, but likely isn't needed since each CRTC here is a purely + * virtual one in the first place. + * + * Pretend we have three screens in both the old and new solutions, but the + * middle one switched IDs from 2 to 4. Doing some complicated mapping + * wouldn't really lead to a different result, since we'd need to drop and + * re-add the virtual screen with a different size anyway. Just naïvely + * matching screen counts, however, has the added benefit of less virtual + * screen removals and additions if only metadata changed, but not the + * actual virtual screens count. */ - while (number != pScrPriv->numCrtcs) { - if (number < pScrPriv->numCrtcs) { + while (new_crtcs_count != pScrPriv->numCrtcs) { + if (new_crtcs_count < pScrPriv->numCrtcs) { #ifdef DEBUG fprintf(stderr, "nxagentAdjustRandRXinerama: destroying crtc\n"); #endif @@ -6895,9 +7199,8 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) #endif /* - * set gamma. Currently the only reason for doing this is - * preventing the xrandr command from complaining about missing - * gamma. + * 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) { @@ -6908,20 +7211,23 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } } - /* delete superfluous non-NX outputs */ + /* Delete superfluous non-NX outputs. */ 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--) { + /* + * At this stage only NX outputs are left - we delete the superfluous + * ones. + */ + for (i = pScrPriv->numOutputs - 1; i >= new_crtcs_count; i--) { nxagentDropOutput(pScrPriv->outputs[i]); } - /* add and init outputs */ - for (i = 0; i < number; i++) { + /* Add and init outputs. */ + for (i = 0; i < new_crtcs_count; i++) { if (i >= pScrPriv->numOutputs) { sprintf(name, "NX%d", i+1); output = RROutputCreate(pScreen, name, strlen(name), NULL); @@ -6947,31 +7253,15 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RROutputSetPhysicalSize(output, 0, 0); } + nxagentScreenBoxesElem *cur_screen_box = xorg_list_first_entry(&(solution->solution_boxes->head), nxagentScreenBoxesElem, entry); for (i = 0; i < pScrPriv->numOutputs; i++) { - Bool disable_output = FALSE; RRModePtr mymode = NULL, prevmode = NULL; - int new_x = 0; - int new_y = 0; - unsigned int new_w = 0; - unsigned int new_h = 0; - - /* 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 + const int new_x = cur_screen_box->box->x1, + new_y = cur_screen_box->box->y2; + const unsigned int new_w = (cur_screen_box->box->x2 - cur_screen_box->box->x1), + new_h = (cur_screen_box->box->y2 - cur_screen_box->box->y2); - /* save previous mode */ + /* Save previous mode. */ prevmode = pScrPriv->crtcs[i]->mode; #ifdef DEBUG if (prevmode) { @@ -6982,103 +7272,75 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) } #endif + /* Map output to CRTC. */ RROutputSetCrtcs(pScrPriv->outputs[i], &(pScrPriv->crtcs[i]), 1); - if (disable_output) { - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: no (valid) intersection - disconnecting\n", i, pScrPriv->outputs[i]->name); - #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 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 output [%d] name [%s]\n", i, pScrPriv->outputs[i]->name); - #endif - RROutputSetModes(pScrPriv->outputs[i], NULL, 0, 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 { - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: intersection is x [%d] y [%d] width [%d] height [%d]\n", i, pScrPriv->outputs[i]->name, new_x, new_y, new_w, new_h); - #endif + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: CRTC is x [%d] y [%d] width [%d] height [%d]\n", i, pScrPriv->outputs[i]->name, new_x, new_y, new_w, new_h); + #endif - RROutputSetConnection(pScrPriv->outputs[i], RR_Connected); + RROutputSetConnection(pScrPriv->outputs[i], RR_Connected); - memset(&modeInfo, '\0', sizeof(modeInfo)); + memset(&modeInfo, '\0', sizeof(modeInfo)); #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); + /* + * 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); #else - sprintf(name, "%dx%d", new_w, new_h); + sprintf(name, "%dx%d", new_w, new_h); #endif - 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); + 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); - mymode = RRModeGet(&modeInfo, name); + mymode = RRModeGet(&modeInfo, name); #ifdef DEBUG - if (mymode) { - fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: mode [%s] ([%p]) created/received, refcnt [%d]\n", i, pScrPriv->outputs[i]->name, name, (void *) mymode, mymode->refcnt); - } - else { - /* FIXME: what is the correct behaviour in this case? */ - fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: mode [%s] creation failed!\n", i, pScrPriv->outputs[i]->name, name); - } + if (mymode) { + fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: mode [%s] ([%p]) created/received, refcnt [%d]\n", i, pScrPriv->outputs[i]->name, name, (void *) mymode, mymode->refcnt); + } + else { + /* FIXME: what is the correct behaviour in this case? */ + fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: mode [%s] creation failed!\n", i, pScrPriv->outputs[i]->name, name); + } #endif - if (prevmode && mymode == prevmode) { - #ifdef DEBUG - fprintf(stderr, "nxagentAdjustRandRXinerama: mymode [%s] ([%p]) == prevmode [%s] ([%p])\n", mymode->name, (void *) mymode, prevmode->name, (void *)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 [%s]\n", mymode->name, (void *) mymode, mymode->refcnt, i, pScrPriv->outputs[i]->name); - #endif - RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0); - } + if (prevmode && mymode == prevmode) { + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: mymode [%s] ([%p]) == prevmode [%s] ([%p])\n", mymode->name, (void *) mymode, prevmode->name, (void *)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 crtc %d\n", mymode->name, (void *) mymode, mymode->refcnt, i); + fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for output %d [%s]\n", mymode->name, (void *) mymode, mymode->refcnt, i, pScrPriv->outputs[i]->name); #endif - RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i])); - } /* if disable_output */ + RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0); + } + + #ifdef DEBUG + fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for crtc %d\n", mymode->name, (void *) 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 + * try to free it again on shutdown. */ if (prevmode && prevmode->refcnt == 1) { #ifdef DEBUG @@ -7089,11 +7351,20 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) RROutputChanged(pScrPriv->outputs[i], TRUE); RRCrtcChanged(pScrPriv->crtcs[i], TRUE); + + cur_screen_box = xorg_list_first_entry(&(cur_screen_box->entry), nxagentScreenBoxesElem, entry); } - /* release allocated memory */ - free(screeninfo); - screeninfo = NULL; + /* Update internal data. */ + nxagentScreenCrtcsSolution *old_solution = nxagentScreenCrtcsTiling; + nxagentScreenCrtcsTiling = solution; + + /* Release allocated memory. */ + nxagentScreenCrtcsFreeSolution(old_solution); + + SAFE_FREE(old_solution); + + SAFE_FREE(screeninfo); #ifdef DEBUG for (i = 0; i < pScrPriv->numCrtcs; i++) { -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch 3.6.x-rpm-debug in repository nx-libs. commit 6e48683e5408f951721c1108e9feb33ad751b8af Author: Mihai Moldovan <ionic@ionic.de> Date: Mon Apr 30 22:10:01 2018 +0200 nx-X11/programs/Xserver/hw/nxagent/Screen.c: remove obsolete intersect_bb() function. --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 79 ----------------------------- 1 file changed, 79 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 5f3ac1d..c0fa440 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -3698,85 +3698,6 @@ static 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 */ -static 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) -{ - - #ifdef DEBUG - fprintf(stderr, "intersect_bb: session window: ([%d],[%d]) [ %d x %d ]\n", ax1, ay1, aw, ah); - fprintf(stderr, "intersect_bb: crtc: ([%d],[%d]) [ %d x %d ]\n", bx1, by1, bw, bh); - fprintf(stderr, "intersect_bb: bounding box: ([%d],[%d]) [ %d x %d ]\n", bbx1, bby1, bbx2-bbx1, bby2-bby1); - #endif - - Bool result = intersect(ax1, ay1, aw, ah, bx1, by1, bw, bh, x, y, w, h); - - if (result == TRUE) { - - /* - * ###### The X-Coordinate ###### - */ - - /* check if outside-left of bounding box */ - if (bx1 == bbx1 && ax1 < bbx1) { - - *w += bbx1 - ax1; - *x = 0; - - #ifdef DEBUG - fprintf(stderr, "intersect_bb: session box is outside-left of the bounding box - width gets adapted to [%d]\n", *w); - #endif - - - } - - /* check if outside-right of bounding box */ - if (bx1 + bw == bbx2 && ax1 + aw > bbx2) { - - *w += ax1 + aw - bbx2; - - #ifdef DEBUG - fprintf(stderr, "intersect_bb: session box is outside-right of the bounding box - width gets adapted to [%d]\n", *w); - #endif - - } - - /* - * ###### The Y-Coordinate ###### - */ - - /* check if outside-above of bounding box */ - if (by1 == bby1 && ay1 < bby1) { - - *h += bby1 - ay1; - *y = 0; - - #ifdef DEBUG - fprintf(stderr, "intersect_bb: session box is outside-above of the bounding box - height gets adapted to [%d]\n", *h); - #endif - - } - - /* check if outside-below of bounding box */ - if (by1 + bh == bby2 && ay1 + ah > bby2) { - - *h += ay1 + ah - bby2; - - #ifdef DEBUG - fprintf(stderr, "intersect_bb: session box is outside-below of the bounding box - height gets adapted to [%d]\n", *h); - #endif - - } - - } - return result; -} -#endif - RRModePtr nxagentRRCustomMode = NULL; /* -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch 3.6.x-rpm-debug in repository nx-libs. commit db0a00aee65f18e5f7117a3c939686d99963ea2f Author: Mihai Moldovan <ionic@ionic.de> Date: Mon Apr 30 22:11:19 2018 +0200 nx-X11/programs/Xserver/hw/nxagent/Imakefile: remove obsolete NXAGENT_RANDR_XINERAMA_CLIPPING macro. --- nx-X11/programs/Xserver/hw/nxagent/Imakefile | 1 - 1 file changed, 1 deletion(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile index 26374f8..f9f86bc 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile +++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile @@ -218,7 +218,6 @@ INCLUDES = \ # 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>x<y>) RandR modes -# NXAGENT_RANDR_XINERAMA_CLIPPING cut off invisible window parts in xinerama mode (you probably do not want this) #if nxVersion NX_DEFINES = \ -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch 3.6.x-rpm-debug in repository nx-libs. commit b96fc6c14c3686654d9fa5e91222bec8589e371b Merge: 9b63cf8 db0a00a Author: Mihai Moldovan <ionic@ionic.de> Date: Tue May 1 04:26:50 2018 +0200 Merge branch 'bugfix/xinerama-crtcs' into 3.6.x-rpm-debug nx-X11/programs/Xserver/hw/nxagent/Screen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git