aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/output.c91
-rw-r--r--src/output.h11
-rw-r--r--src/ramps.c44
-rw-r--r--src/ramps.h14
-rw-r--r--src/server.c19
5 files changed, 175 insertions, 4 deletions
diff --git a/src/output.c b/src/output.c
index b2085db..25a332a 100644
--- a/src/output.c
+++ b/src/output.c
@@ -24,6 +24,13 @@
/**
+ * The name of the process
+ */
+extern char* argv0;
+
+
+
+/**
* Free all resources allocated to an output.
* The allocation of `output` itself is not freed,
* nor is its the libgamma destroyed.
@@ -310,7 +317,7 @@ ssize_t add_filter(struct output* out, struct filter* filter)
/**
* Recalculate the resulting gamma and
- * update push the new gamam ramps to the CRTC
+ * update push the new gamma ramps to the CRTC
*
* @param output The output
* @param first_updated The index of the first added or removed filter
@@ -318,7 +325,87 @@ ssize_t add_filter(struct output* out, struct filter* filter)
*/
int flush_filters(struct output* output, size_t first_updated)
{
- /* TODO */ (void) output, (void) first_updated;
+ union gamma_ramps plain;
+ union gamma_ramps* last;
+ size_t i;
+ int r = 0;
+
+ if (first_updated == 0)
+ {
+ if (make_plain_ramps(&plain, output) < 0)
+ return -1;
+ last = &plain;
+ }
+ else
+ last = output->table_sums + (first_updated - 1);
+
+ for (i = first_updated; i < output->table_size; i++)
+ {
+ apply(output->table_sums + i, output->table_filters[i].ramps, output->depth, last);
+ last = output->table_sums + i;
+ }
+
+ switch (output->depth)
+ {
+ case 8: r = libgamma_crtc_set_gamma_ramps8(output->crtc, last->u8); break;
+ case 16: r = libgamma_crtc_set_gamma_ramps16(output->crtc, last->u16); break;
+ case 32: r = libgamma_crtc_set_gamma_ramps32(output->crtc, last->u32); break;
+ case 64: r = libgamma_crtc_set_gamma_ramps64(output->crtc, last->u64); break;
+ case -1: r = libgamma_crtc_set_gamma_rampsf(output->crtc, last->f); break;
+ case -2: r = libgamma_crtc_set_gamma_rampsd(output->crtc, last->d); break;
+ default:
+ abort();
+ }
+ if (r)
+ libgamma_perror(argv0, r); /* Not fatal */
+
+ if (first_updated == 0)
+ libgamma_gamma_ramps8_destroy(&(plain.u8));
+
+ return 0;
+}
+
+
+/**
+ * Make identity mapping ramps
+ *
+ * @param ramps Output parameter for the ramps
+ * @param output The output for which the ramps shall be configured
+ * @return Zero on success, -1 on error
+ */
+int make_plain_ramps(union gamma_ramps* ramps, struct output* output)
+{
+ COPY_RAMP_SIZES(&(ramps->u8), output);
+ switch (output->depth)
+ {
+ case 8:
+ if (libgamma_gamma_ramps8_initialise(&(ramps->u8)))
+ return -1;
+ break;
+ case 16:
+ if (libgamma_gamma_ramps16_initialise(&(ramps->u16)))
+ return -1;
+ break;
+ case 32:
+ if (libgamma_gamma_ramps32_initialise(&(ramps->u32)))
+ return -1;
+ break;
+ case 64:
+ if (libgamma_gamma_ramps64_initialise(&(ramps->u64)))
+ return -1;
+ break;
+ case -1:
+ if (libgamma_gamma_rampsf_initialise(&(ramps->f)))
+ return -1;
+ break;
+ case -2:
+ if (libgamma_gamma_rampsd_initialise(&(ramps->d)))
+ return -1;
+ break;
+ default:
+ abort();
+ }
+ /* TODO fill ramps (use libclut) */
return 0;
}
diff --git a/src/output.h b/src/output.h
index 8d59eec..a75ebfa 100644
--- a/src/output.h
+++ b/src/output.h
@@ -199,7 +199,7 @@ ssize_t add_filter(struct output* output, struct filter* filter);
/**
* Recalculate the resulting gamma and
- * update push the new gamam ramps to the CRTC
+ * update push the new gamma ramps to the CRTC
*
* @param output The output
* @param first_updated The index of the first added or removed filter
@@ -207,3 +207,12 @@ ssize_t add_filter(struct output* output, struct filter* filter);
*/
int flush_filters(struct output* output, size_t first_updated);
+/**
+ * Make identity mapping ramps
+ *
+ * @param ramps Output parameter for the ramps
+ * @param output The output for which the ramps shall be configured
+ * @return Zero on success, -1 on error
+ */
+int make_plain_ramps(union gamma_ramps* ramps, struct output* output);
+
diff --git a/src/ramps.c b/src/ramps.c
index b7ad978..d8d4975 100644
--- a/src/ramps.c
+++ b/src/ramps.c
@@ -94,3 +94,47 @@ size_t gamma_ramps_unmarshal(union gamma_ramps* this, const void* buf, size_t ra
return ramps_size;
}
+
+/**
+ * Apply a ramp-trio on top of another ramp-trio
+ *
+ * @param dest The output for the resulting ramp-trio, must be initialised
+ * @param application The red, green and blue ramps, as one single raw array,
+ * of the filter that should be applied
+ * @param depth -1: `float` stops
+ * -2: `double` stops
+ * Other: the number of bits of each (integral) stop
+ * @param base The CLUT on top of which the new filter should be applied,
+ * this can be the same pointer as `dest`
+ */
+void apply(union gamma_ramps* dest, void* application, int depth, union gamma_ramps* base)
+{
+ union gamma_ramps app;
+ size_t bytedepth;
+ size_t red_width, green_width, blue_width;
+
+ if (depth == -1)
+ bytedepth = sizeof(float);
+ else if (depth == -2)
+ bytedepth = sizeof(double);
+ else
+ bytedepth = (size_t)depth / 8;
+
+ red_width = (app.u8.red_size = base->u8.red_size) * bytedepth;
+ green_width = (app.u8.green_size = base->u8.green_size) * bytedepth;
+ blue_width = (app.u8.blue_size = base->u8.blue_size) * bytedepth;
+
+ app.u8.red = application;
+ app.u8.green = app.u8.red + red_width;
+ app.u8.blue = app.u8.green + green_width;
+
+ if (dest != base)
+ {
+ memcpy(dest->u8.red, base->u8.red, red_width);
+ memcpy(dest->u8.green, base->u8.green, green_width);
+ memcpy(dest->u8.blue, base->u8.blue, blue_width);
+ }
+
+ /* TODO apply with libclut */
+}
+
diff --git a/src/ramps.h b/src/ramps.h
index 8261a61..d2b769f 100644
--- a/src/ramps.h
+++ b/src/ramps.h
@@ -81,3 +81,17 @@ size_t gamma_ramps_marshal(const union gamma_ramps* this, void* buf, size_t ramp
*/
size_t gamma_ramps_unmarshal(union gamma_ramps* this, const void* buf, size_t ramps_size);
+/**
+ * Apply a ramp-trio on top of another ramp-trio
+ *
+ * @param dest The output for the resulting ramp-trio, must be initialised
+ * @param application The red, green and blue ramps, as one single raw array,
+ * of the filter that should be applied
+ * @param depth -1: `float` stops
+ * -2: `double` stops
+ * Other: the number of bits of each (integral) stop
+ * @param base The CLUT on top of which the new filter should be applied,
+ * this can be the same pointer as `dest`
+ */
+void apply(union gamma_ramps* dest, void* application, int depth, union gamma_ramps* base);
+
diff --git a/src/server.c b/src/server.c
index d046a95..06d88da 100644
--- a/src/server.c
+++ b/src/server.c
@@ -603,7 +603,24 @@ static int get_gamma(size_t conn, char* message_id, char* crtc, char* coalesce,
n = (size_t)m;
if (coal)
{
- /* TODO coalesce */
+ if (start == 0)
+ memcpy(buf + n, output->table_sums[end].u8.red, output->ramps_size);
+ else
+ {
+ union gamma_ramps ramps;
+ if (make_plain_ramps(&ramps, output))
+ {
+ int saved_errno = errno;
+ free(buf);
+ errno = saved_errno;
+ return -1;
+ }
+ for (i = start; i < end; i++)
+ apply(&ramps, output->table_filters[i].ramps, output->depth, &ramps);
+ memcpy(buf + n, ramps.u8.red, output->ramps_size);
+ libgamma_gamma_ramps8_destroy(&(ramps.u8));
+ }
+ n += output->ramps_size;
}
else
for (i = start; i < end; i++)