[gtk/wip/otte/color-profiles: 109/111] x11: Implement support for color profiles




commit 3de2a29004f793b4b9d7cdfcf14f5ccc18345aed
Author: Benjamin Otte <otte redhat com>
Date:   Fri Oct 1 06:26:59 2021 +0200

    x11: Implement support for color profiles
    
    Stole the implementation from eog.
    
    This doesn't yet update the profile when it changes though.

 gdk/x11/gdkdisplay-x11.c | 80 +++++++++++++++++++++++++++++++++++++++++++++---
 gdk/x11/gdkdisplay-x11.h |  3 ++
 gdk/x11/gdksurface-x11.c |  2 ++
 3 files changed, 80 insertions(+), 5 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 6e5fd276f7..d1f7b1d003 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1401,6 +1401,71 @@ gdk_x11_display_init_leader_surface (GdkX11Display *self)
   self->leader_window_title_set = FALSE;
 }
 
+static void
+voidXFree (gpointer data)
+{
+  XFree (data);
+}
+
+static void
+gdk_x11_display_check_color_profile (GdkX11Display *self)
+{
+  GdkDisplay *display = GDK_DISPLAY (self);
+  GdkX11Screen *screen;
+  char *atom_name;
+  Atom type;
+  int result;
+  int format;
+  gulong nitems;
+  gulong bytes_after;
+  guchar *data;
+  GBytes *bytes;
+
+  screen = self->screen;
+  if (screen->screen_num > 0)
+    atom_name = g_strdup_printf ("_ICC_PROFILE_%d", screen->screen_num);
+  else
+    atom_name = g_strdup ("_ICC_PROFILE");
+
+  g_clear_object (&self->color_profile);
+  self->color_profile = g_object_ref (gdk_color_profile_get_srgb ());
+
+  gdk_x11_display_error_trap_push (display);
+  result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+                               screen->xroot_window,
+                               gdk_x11_get_xatom_by_name_for_display (display, atom_name),
+                               0, G_MAXLONG, False, XA_CARDINAL, &type,
+                               &format, &nitems,
+                               &bytes_after, &data);
+  gdk_x11_display_error_trap_pop_ignored (display);
+
+  g_free (atom_name);
+
+  if (result != Success || type != XA_CARDINAL || nitems <= 0)
+    return;
+
+  switch (format)
+    {
+    case 8:
+      bytes = g_bytes_new_with_free_func (data, nitems, voidXFree, data);
+      break;
+    case 16:
+      bytes = g_bytes_new_with_free_func (data, sizeof (short) * nitems, voidXFree, data);
+      break;
+    case 32:
+      bytes = g_bytes_new_with_free_func (data, sizeof (long) * nitems, voidXFree, data);
+      break;
+    default:
+      XFree (data);
+      return;
+    }
+
+  g_clear_object (&self->color_profile);
+  self->color_profile = gdk_color_profile_new_from_icc_bytes (bytes, NULL);
+  if (!self->color_profile)
+    self->color_profile = g_object_ref (gdk_color_profile_get_srgb ());
+}
+
 /**
  * gdk_x11_display_open:
  * @display_name: (nullable): name of the X display.
@@ -1468,6 +1533,9 @@ gdk_x11_display_open (const char *display_name)
   /* initialize the display's screens */ 
   display_x11->screen = _gdk_x11_screen_new (display, DefaultScreen (display_x11->xdisplay));
 
+  /* We want this for the leader surface already */
+  gdk_x11_display_check_color_profile (display_x11);
+
   /* If GL is available we want to pick better default/rgba visuals,
    * as we care about GLX details such as alpha/depth/stencil depth,
    * stereo and double buffering
@@ -1913,15 +1981,17 @@ gdk_x11_display_ungrab (GdkDisplay *display)
 static void
 gdk_x11_display_dispose (GObject *object)
 {
-  GdkX11Display *display_x11 = GDK_X11_DISPLAY (object);
+  GdkX11Display *self = GDK_X11_DISPLAY (object);
 
-  if (display_x11->event_source)
+  if (self->event_source)
     {
-      g_source_destroy (display_x11->event_source);
-      g_source_unref (display_x11->event_source);
-      display_x11->event_source = NULL;
+      g_source_destroy (self->event_source);
+      g_source_unref (self->event_source);
+      self->event_source = NULL;
     }
 
+  g_clear_object (&self->color_profile);
+
   G_OBJECT_CLASS (gdk_x11_display_parent_class)->dispose (object);
 }
 
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index 78aece4177..e57f10e5ea 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -128,6 +128,9 @@ struct _GdkX11Display
   guint have_damage;
 #endif
 
+  /* Stored in the ICC_PROFILE rootwindow prop */
+  GdkColorProfile *color_profile;
+
   /* If GL is not supported, store the error here */
   GError *gl_error;
 
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index 064e21964e..1b296bc084 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -1011,6 +1011,8 @@ setup_toplevel_window (GdkSurface    *surface,
   
   /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
   XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
+
+  gdk_surface_set_color_profile (surface, GDK_X11_DISPLAY (display)->color_profile);
   
   if (!gdk_running_in_sandbox ())
     {


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