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 af889ab489d013bf19f5559ce6dae3db205a0f42 Author: Mihai Moldovan <io...@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 | 162 ++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index b66249a..2d477cb 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -6573,6 +6573,168 @@ 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); + } + + nxagentScreenBoxes *initial_screens = calloc(1, sizeof(nxagentScreenBoxes)); + + if (!(initial_screens)) { + nxagentFreeScreenBoxes(boxes, TRUE); + + return(ret); + } + + 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 _______________________________________________ x2go-commits mailing list x2go-commits@lists.x2go.org https://lists.x2go.org/listinfo/x2go-commits