diff options
Diffstat (limited to 'src/gammad.c')
-rw-r--r-- | src/gammad.c | 58 |
1 files changed, 54 insertions, 4 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: |