[mutter] color-manager/x11: Set color transformation matrix



commit 39e01d87001443bfc3ec7e212a18f42b289fc49f
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Dec 6 15:56:51 2021 +0100

    color-manager/x11: Set color transformation matrix
    
    As was done in gsd-color, set the "CTM" of the output. This is only done
    in X11, as it was only ever implemented for X11.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2166>

 src/backends/x11/meta-color-manager-x11.c | 98 +++++++++++++++++++++++++++++--
 1 file changed, 94 insertions(+), 4 deletions(-)
---
diff --git a/src/backends/x11/meta-color-manager-x11.c b/src/backends/x11/meta-color-manager-x11.c
index 8f1e6370b0..fbe7357c1c 100644
--- a/src/backends/x11/meta-color-manager-x11.c
+++ b/src/backends/x11/meta-color-manager-x11.c
@@ -93,11 +93,10 @@ ensure_srgb_profile_bytes (MetaColorManagerX11 *color_manager_x11)
 }
 
 static void
-on_color_device_updated (MetaColorManager *color_manager,
-                         MetaColorDevice  *color_device)
+update_root_window_atom (MetaColorManagerX11 *color_manager_x11,
+                         MetaColorDevice     *color_device)
 {
-  MetaColorManagerX11 *color_manager_x11 =
-    META_COLOR_MANAGER_X11 (color_manager);
+  MetaColorManager *color_manager = META_COLOR_MANAGER (color_manager_x11);
   MetaBackend *backend = meta_color_manager_get_backend (color_manager);
   MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
   Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
@@ -170,6 +169,97 @@ on_color_device_updated (MetaColorManager *color_manager,
     }
 }
 
+static uint64_t
+double_to_ctmval (double value)
+{
+  uint64_t sign = value < 0;
+  double integer, fractional;
+
+  if (sign)
+    value = -value;
+
+  fractional = modf (value, &integer);
+
+  return
+    sign << 63 |
+    (uint64_t) integer << 32 |
+    (uint64_t) (fractional * 0xffffffffUL);
+}
+
+static MetaOutputCtm
+mat33_to_ctm (CdMat3x3 matrix)
+{
+  MetaOutputCtm ctm;
+
+  /*
+   * libcolord generates a matrix containing double values. RandR's CTM
+   * property expects values in S31.32 fixed-point sign-magnitude format
+   */
+  ctm.matrix[0] = double_to_ctmval (matrix.m00);
+  ctm.matrix[1] = double_to_ctmval (matrix.m01);
+  ctm.matrix[2] = double_to_ctmval (matrix.m02);
+  ctm.matrix[3] = double_to_ctmval (matrix.m10);
+  ctm.matrix[4] = double_to_ctmval (matrix.m11);
+  ctm.matrix[5] = double_to_ctmval (matrix.m12);
+  ctm.matrix[6] = double_to_ctmval (matrix.m20);
+  ctm.matrix[7] = double_to_ctmval (matrix.m21);
+  ctm.matrix[8] = double_to_ctmval (matrix.m22);
+
+  return ctm;
+}
+
+static void
+update_device_ctm (MetaColorManagerX11 *color_manager_x11,
+                   MetaColorDevice     *color_device)
+{
+  MetaMonitor *monitor;
+  MetaColorProfile *color_profile;
+  CdIcc *srgb_cd_icc;
+  g_autoptr (GError) error = NULL;
+  CdIcc *cd_icc;
+  CdMat3x3 csc;
+  MetaOutputCtm ctm;
+  MetaOutput *output;
+  MetaOutputXrandr *output_xrandr;
+
+  monitor = meta_color_device_get_monitor (color_device);
+  if (!meta_monitor_supports_color_transform (monitor))
+    return;
+
+  color_profile = meta_color_device_get_assigned_profile (color_device);
+  if (!color_profile)
+    return;
+
+  srgb_cd_icc = ensure_srgb_profile (color_manager_x11);
+  if (!srgb_cd_icc)
+    return;
+
+  cd_icc = meta_color_profile_get_cd_icc (color_profile);
+  if (!cd_icc_utils_get_adaptation_matrix (cd_icc, srgb_cd_icc, &csc, &error))
+    {
+      g_warning_once ("Failed to calculate adaption matrix: %s",
+                      error->message);
+      return;
+    }
+
+  ctm = mat33_to_ctm (csc);
+
+  output = meta_monitor_get_main_output (monitor);
+  output_xrandr = META_OUTPUT_XRANDR (output);
+  meta_output_xrandr_set_ctm (output_xrandr, &ctm);
+}
+
+static void
+on_color_device_updated (MetaColorManager *color_manager,
+                         MetaColorDevice  *color_device)
+{
+  MetaColorManagerX11 *color_manager_x11 =
+    META_COLOR_MANAGER_X11 (color_manager);
+
+  update_root_window_atom (color_manager_x11, color_device);
+  update_device_ctm (color_manager_x11, color_device);
+}
+
 static void
 meta_color_manager_x11_constructed (GObject *object)
 {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]