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 bd0e131193ac07a2fbc78fcd88571fbe9de76445
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 | 291 ++++++++++++++++++++++++++++
 1 file changed, 291 insertions(+)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c 
b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 44ad539..1982875 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -6714,6 +6714,297 @@ static nxagentScreenCrtcsSolutions* 
nxagentScreenCrtcsGenerateSolutions(const nx
 
   ret = best_ret;
 
+  return(ret);
+}
+
+/* Helper printing out a screen boxes list. */
+static char* nxagentPrintScreenBoxes(const nxagentScreenBoxes *boxes) {
+  char *ret = NULL;
+
+  if ((!(boxes))) {
+    return(ret);
+  }
+
+  char *construct = NULL;
+  if (xorg_list_is_empty(&(boxes->head))) {
+    if (-1 == asprintf(&construct, "empty")) {
+      return(ret);
+    }
+  }
+  else {
+    size_t total_length = 512,
+           last_pos = 0;
+    construct = calloc(total_length, sizeof(char));
+
+    if (!(construct)) {
+      return(ret);
+    }
+
+    nxagentScreenBoxesElem *cur = NULL;
+    xorg_list_for_each_entry(cur, &(boxes->head), entry) {
+      char *box_str = nxagentPrintScreenBoxesElem(cur);
+
+      if (!(box_str)) {
+        SAFE_FREE(construct);
+      }
+      else {
+        const size_t box_str_raw_len = (strlen(box_str) + 1);
+
+        /*                    v-- implicit " -- " chars */
+        while (((box_str_raw_len + 4) + last_pos) > total_length) {
+          /* Buffer space needs to be expanded. */
+          total_length += 512;
+          char *new_construct = realloc(construct, total_length);
+
+          if (!(new_construct)) {
+            SAFE_FREE(construct);
+
+            break;
+          }
+          else {
+            construct = new_construct;
+
+            memset((construct + last_pos), 0, (total_length - last_pos));
+          }
+        }
+
+        if (construct) {
+          const size_t write_count = snprintf((construct + last_pos), 
(total_length - last_pos), "%s -- ", box_str);
+
+          if (0 > write_count) {
+            const int errno_save = errno;
+
+            fprintf(stderr, "%s: error writing box string representation to 
buffer: %s\n", __func__, strerror(errno_save));
+
+            SAFE_FREE(construct);
+          }
+          else if (write_count >= (total_length - last_pos)) {
+            fprintf(stderr, "%s: buffer was too small to hold new box string 
representation. Algorithm error.\n", __func__);
+
+            SAFE_FREE(construct);
+          }
+          else {
+            last_pos += write_count;
+          }
+        }
+      }
+
+      SAFE_FREE(box_str);
+
+      if (!(construct)) {
+        break;
+      }
+    }
+
+    if (construct) {
+      /* Drop the last delimiter (" -- ") character string. */
+      construct[last_pos - 4] = 0;
+    }
+  }
+
+  ret = construct;
+
+  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);
+
+#ifdef DEBUG
+  fprintf(stderr, "%s: merged initial screens into initial_screens, all boxes 
should be correctly marked.\n", __func__);
+
+  fprintf(stderr, "%s: dumping initial_screens:\n", __func__);
+  {
+    char *initial_screens_str = nxagentPrintScreenBoxes(initial_screens);
+
+    if (initial_screens_str) {
+      fprintf(stderr, "%s:   %s\n", __func__, initial_screens_str);
+    }
+    else {
+      fprintf(stderr, "%s:   error!\n", __func__);
+    }
+
+    SAFE_FREE(initial_screens_str);
+  }
+
+  fprintf(stderr, "%s: dumping all boxes:\n", __func__);
+  {
+    char *boxes_str = nxagentPrintScreenBoxes(boxes);
+
+    if (boxes_str) {
+      fprintf(stderr, "%s:   %s\n", __func__, boxes_str);
+    }
+    else {
+      fprintf(stderr, "%s:   error!\n", __func__);
+    }
+
+    SAFE_FREE(boxes_str);
+  }
+#endif
+
+  /* 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);
+  nxagentFreeScreenBoxes(boxes, TRUE);
+
+  SAFE_FREE(initial_screens);
+  SAFE_FREE(boxes);
+
+  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

Reply via email to