aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/gamma-wayland.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/gamma-wayland.c99
1 files changed, 85 insertions, 14 deletions
diff --git a/src/lib/gamma-wayland.c b/src/lib/gamma-wayland.c
index b9a8663..ceeacd5 100644
--- a/src/lib/gamma-wayland.c
+++ b/src/lib/gamma-wayland.c
@@ -74,13 +74,23 @@ static void registry_global_remover(void* site_state, struct wl_registry* regist
* @param control The gamma ramp controll for the CRTC
* @param size The number of stops in the gamma ramps of the CRTC
*/
-static void gamma_control_gamma_size(void* crtc, struct gamma_control* control, uint32_t size);
+static void gamma_control_gamma_size(void* crtc_data, struct gamma_control* control, uint32_t size);
+
+/**
+ * This function is invoked when the display server
+ * tells us that a request has been completed.
+ *
+ * @param crtc_data The protocol-specific data for the CRTC
+ * @param callback The callback
+ * @param request_data Request-specific callback data
+ */
+static void display_synced(void* crtc_data, struct wl_callback* callback, uint32_t request_data);
/**
* This function is called when the display server
* tells us about an output's geometry.
*
- * @param info_ The CRTC's information structure to fill
+ * @param crtc_data The protocol-specific data for the CRTC
* @param output The output
* @param x The left position, within the global compositor space, of the output
* @param y The top position, within the global compositor space, of the output
@@ -91,7 +101,7 @@ static void gamma_control_gamma_size(void* crtc, struct gamma_control* control,
* @param model Textual description of the monitor's model
* @param transform Output flipping and rotation
*/
-static void geometry(void* info_, struct wl_output* output, int32_t x, int32_t y,
+static void geometry(void* crtc_data, struct wl_output* output, int32_t x, int32_t y,
int32_t physical_width, int32_t physical_height, int32_t subpixel_,
const char* make, const char* model, int32_t transform);
@@ -108,6 +118,11 @@ typedef struct libgamma_wayland_crtc_data
struct wl_output* output;
/**
+ * Display synchronisation callback.
+ */
+ struct wl_callback* display_sync;
+
+ /**
* Gamma controller for the output.
*/
struct gamma_control* gamma_control;
@@ -133,10 +148,20 @@ typedef struct libgamma_wayland_crtc_data
uint32_t global_id;
/**
- * Whether the CRTC has been removed;
+ * Whether the CRTC has been removed.
*/
int removed;
+ /**
+ * Whether the CRTC have an geometry listener assigned.
+ */
+ int have_geometry_listener;
+
+ /**
+ * The output's geometry.
+ */
+ libgamma_crtc_information_t geometry;
+
} libgamma_wayland_crtc_data_t;
@@ -220,6 +245,11 @@ static const struct wl_output_listener output_listener =
NULL,
};
+static const struct wl_callback_listener display_sync_listener =
+ {
+ display_synced,
+ };
+
/**
@@ -421,14 +451,21 @@ void libgamma_wayland_site_destroy(libgamma_site_state_t* restrict this)
{
libgamma_wayland_site_data_t* data = this->data;
libgamma_wayland_crtc_data_t* crtc;
- gamma_control_manager_destroy(data->gamma_control_manager);
- wl_registry_destroy(data->registry);
- wl_display_disconnect(data->display);
+ if (data->gamma_control_manager != NULL)
+ gamma_control_manager_destroy(data->gamma_control_manager);
+ if (data->registry != NULL)
+ wl_registry_destroy(data->registry);
+ if (data->display != NULL)
+ wl_display_disconnect(data->display);
while (data->crtcs_available--)
{
crtc = data->crtcs[data->crtcs_available];
- gamma_control_destroy(crtc->gamma_control);
- wl_output_destroy(crtc->output);
+ if (crtc->gamma_control != NULL)
+ gamma_control_destroy(crtc->gamma_control);
+ if (crtc->output != NULL)
+ wl_output_destroy(crtc->output);
+ if (crtc->display_sync != NULL)
+ wl_callback_destroy(crtc->display_sync);
free(crtc);
}
free(data->crtcs);
@@ -594,7 +631,7 @@ int libgamma_wayland_crtc_restore(libgamma_crtc_state_t* restrict this)
* This function is called when the display server
* tells us about an output's geometry.
*
- * @param info_ The CRTC's information structure to fill
+ * @param crtc_data The protocol-specific data for the CRTC
* @param output The output
* @param x The left position, within the global compositor space, of the output
* @param y The top position, within the global compositor space, of the output
@@ -605,11 +642,12 @@ int libgamma_wayland_crtc_restore(libgamma_crtc_state_t* restrict this)
* @param model Textual description of the monitor's model
* @param transform Output flipping and rotation
*/
-static void geometry(void* info_, struct wl_output* output, int32_t x, int32_t y,
+static void geometry(void* crtc_data, struct wl_output* output, int32_t x, int32_t y,
int32_t physical_width, int32_t physical_height, int32_t subpixel_,
const char* make, const char* model, int32_t transform)
{
- libgamma_crtc_information_t* info = info_;
+ libgamma_wayland_crtc_data_t* data = crtc_data;
+ libgamma_crtc_information_t* info = &(data->geometry);
enum wl_output_subpixel subpixel = subpixel_;
(void) output;
@@ -660,6 +698,7 @@ int libgamma_wayland_get_crtc_information(libgamma_crtc_information_t* restrict
#define _E(FIELD) _EE(FIELD, LIBGAMMA_CRTC_INFO_NOT_SUPPORTED)
libgamma_wayland_crtc_data_t* data = crtc->data;
+ libgamma_wayland_site_data_t* site = crtc->partition->site->data;
int e = 0;
/* Wipe all error indicators. */
@@ -672,9 +711,15 @@ int libgamma_wayland_get_crtc_information(libgamma_crtc_information_t* restrict
this->subpixel_order_error = _EE(LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER, LIBGAMMA_OUTPUT_INFORMATION_QUERY_FAILED);
if (this->width_mm_error || this->height_mm_error || this->subpixel_order_error)
{
- /* TODO add listener and wait for events */
+ if (data->have_geometry_listener == 0)
+ {
+ data->have_geometry_listener = 1;
+ data->geometry = *this;
+ wl_output_add_listener(data->output, &output_listener, data);
+ wl_display_roundtrip(site->display);
+ }
+ *this = data->geometry;
e |= this->width_mm_error | this->height_mm_error | this->subpixel_order_error;
- /* TODO remove listener */
}
@@ -729,6 +774,25 @@ int libgamma_wayland_crtc_get_gamma_ramps16(libgamma_crtc_state_t* restrict this
/**
+ * This function is invoked when the display server
+ * tells us that a request has been completed.
+ *
+ * @param crtc_data The protocol-specific data for the CRTC
+ * @param callback The callback
+ * @param request_data Request-specific callback data
+ */
+static void display_synced(void* crtc_data, struct wl_callback* callback, uint32_t request_data)
+{
+ libgamma_wayland_crtc_data_t* crtc = crtc_data;
+
+ (void) request_data;
+
+ crtc->display_sync = NULL;
+ wl_callback_destroy(callback);
+}
+
+
+/**
* Set the gamma ramps for a CRTC, 16-bit gamma-depth version.
*
* @param this The CRTC state.
@@ -744,6 +808,7 @@ int libgamma_wayland_crtc_set_gamma_ramps16(libgamma_crtc_state_t* restrict this
struct wl_array red;
struct wl_array green;
struct wl_array blue;
+ int r = 0;
/* Verify that gamma can be set. */
#ifdef DEBUG
@@ -770,7 +835,13 @@ int libgamma_wayland_crtc_set_gamma_ramps16(libgamma_crtc_state_t* restrict this
/* Apply gamma ramps. */
gamma_control_set_gamma(crtc->gamma_control, &red, &green, &blue);
+ crtc->display_sync = wl_display_sync(site->display);
+ wl_callback_add_listener(crtc->display_sync, &display_sync_listener, crtc);
wl_display_flush(site->display);
+ while (crtc->display_sync && (r >= 0))
+ r = wl_display_dispatch(site->display);
+ if (r < 0)
+ return LIBGAMMA_GAMMA_RAMP_WRITE_FAILED;
/* TODO Check for errors. */