aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gammad.c58
-rw-r--r--src/output.c3
-rw-r--r--src/output.h3
3 files changed, 58 insertions, 6 deletions
diff --git a/src/gammad.c b/src/gammad.c
index 9cb0106..254dd52 100644
--- a/src/gammad.c
+++ b/src/gammad.c
@@ -1084,8 +1084,11 @@ static size_t unmarshal(void* buf)
*/
static int unmarshal_and_merge_state(const char* statefile)
{
- struct output* old_outputs = outputs;
- size_t i, j, _n, old_outputs_n = outputs_n;
+ struct output* new_outputs = outputs;
+ struct output* old_outputs = NULL;
+ size_t new_outputs_n = outputs_n;
+ size_t old_outputs_n = 0;
+ size_t i, j, k;
void* marshalled = NULL;
int fd = -1, saved_errno;
@@ -1095,7 +1098,7 @@ static int unmarshal_and_merge_state(const char* statefile)
fd = open(statefile, O_RDONLY);
if (fd < 0)
goto fail;
- if (!(marshalled = nread(fd, &_n)))
+ if (!(marshalled = nread(fd, &k)))
goto fail;
close(fd), fd = -1;
unlink(statefile), statefile = NULL;
@@ -1104,7 +1107,54 @@ static int unmarshal_and_merge_state(const char* statefile)
goto fail;
free(marshalled), marshalled = NULL;
- /* TODO merge */
+ old_outputs = outputs, outputs = new_outputs, new_outputs = NULL;
+ old_outputs_n = outputs_n, outputs_n = new_outputs_n, new_outputs_n = 0;
+
+ i = j = new_outputs_n = 0;
+ while ((i < old_outputs_n) && (j < outputs_n))
+ {
+ int cmp = strcmp(old_outputs[i].name, outputs[j].name);
+ if (cmp <= 0)
+ new_outputs_n++;
+ i += cmp >= 0;
+ j += cmp <= 0;
+ }
+ new_outputs_n += outputs_n - j;
+
+ new_outputs = calloc(new_outputs_n, sizeof(*new_outputs));
+ if (new_outputs == NULL)
+ goto fail;
+
+ i = j = k = new_outputs_n = 0;
+ while ((i < old_outputs_n) && (j < outputs_n))
+ {
+ int cmp = strcmp(old_outputs[i].name, outputs[j].name);
+ int is_same = 0;
+ if (cmp == 0)
+ is_same = (old_outputs[i].depth == outputs[j].depth &&
+ old_outputs[i].red_size == outputs[j].red_size &&
+ old_outputs[i].green_size == outputs[j].green_size &&
+ old_outputs[i].blue_size == outputs[j].blue_size);
+ if (is_same)
+ {
+ new_outputs[k] = old_outputs[i];
+ new_outputs[k].crtc = outputs[j].crtc;
+ output_destroy(outputs + j);
+ k++;
+ }
+ else if (cmp <= 0)
+ new_outputs[k++] = outputs[j];
+ i += cmp >= 0;
+ j += cmp <= 0;
+ }
+ while (j < outputs_n)
+ new_outputs[k++] = outputs[j++];
+
+ outputs = new_outputs;
+ outputs_n = new_outputs_n;
+
+ for (i = 0; i < old_outputs_n; i++)
+ output_destroy(old_outputs + i);
return 0;
fail:
diff --git a/src/output.c b/src/output.c
index b0e0c14..3cd7886 100644
--- a/src/output.c
+++ b/src/output.c
@@ -25,7 +25,8 @@
/**
* Free all resources allocated to an output.
- * The allocation of `output` itself is not freed.
+ * The allocation of `output` itself is not freed,
+ * nor is its the libgamma destroyed.
*
* @param this The output
*/
diff --git a/src/output.h b/src/output.h
index aa2ab8b..acd5f63 100644
--- a/src/output.h
+++ b/src/output.h
@@ -135,7 +135,8 @@ struct output
/**
* Free all resources allocated to an output.
- * The allocation of `output` itself is not freed.
+ * The allocation of `output` itself is not freed,
+ * nor is its the libgamma destroyed.
*
* @param this The output
*/