[gnome-color-manager] Drop GcmXserver, GcmScreen and libgnomedesktop3 and make the X11 code faster and cleaner
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Drop GcmXserver, GcmScreen and libgnomedesktop3 and make the X11 code faster and cleaner
- Date: Fri, 23 Jul 2010 14:20:07 +0000 (UTC)
commit a5ccf8ad9eadfef61d9f600494faea5fa9dc753c
Author: Richard Hughes <richard hughsie com>
Date: Fri Jul 23 14:56:51 2010 +0100
Drop GcmXserver, GcmScreen and libgnomedesktop3 and make the X11 code faster and cleaner
configure.ac | 3 +-
contrib/gnome-color-manager.spec.in | 10 +-
docs/api/libcolor-glib-docs.sgml | 3 +-
libcolor-glib/Makefile.am | 7 +-
libcolor-glib/gcm-x11-output.c | 705 +++++++++++++++++++++++++++++++
libcolor-glib/gcm-x11-output.h | 123 ++++++
libcolor-glib/gcm-x11-screen.c | 747 ++++++++++++++++++++++++++++++++
libcolor-glib/gcm-x11-screen.h | 97 +++++
libcolor-glib/gcm-xserver.c | 794 -----------------------------------
libcolor-glib/gcm-xserver.h | 111 -----
libcolor-glib/libcolor-glib.h | 3 +-
src/Makefile.am | 12 -
src/gcm-calibrate-argyll.c | 10 +-
src/gcm-client.c | 96 +++--
src/gcm-device-xrandr.c | 242 +++--------
src/gcm-device-xrandr.h | 4 +-
src/gcm-inspect.c | 39 +-
src/gcm-screen.c | 220 ----------
src/gcm-screen.h | 86 ----
tools/Makefile.am | 3 +-
tools/gcm-dump-edid.c | 59 ++-
21 files changed, 1870 insertions(+), 1504 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d34767d..aa540d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,9 +136,8 @@ dnl ---------------------------------------------------------------------------
dnl - Check library dependencies
dnl ---------------------------------------------------------------------------
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.14.0 gobject-2.0 gthread-2.0 gio-2.0 >= 2.25.9)
-PKG_CHECK_MODULES(XORG, xxf86vm xrandr)
+PKG_CHECK_MODULES(XORG, xrandr)
PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 2.90.3)
-PKG_CHECK_MODULES(GNOMEDESKTOP, gnome-desktop-3.0 >= 2.90.0)
PKG_CHECK_MODULES(GUDEV, gudev-1.0)
PKG_CHECK_MODULES(LCMS, lcms2)
PKG_CHECK_MODULES(X11, x11)
diff --git a/contrib/gnome-color-manager.spec.in b/contrib/gnome-color-manager.spec.in
index 21dc3d2..efdf3d4 100644
--- a/contrib/gnome-color-manager.spec.in
+++ b/contrib/gnome-color-manager.spec.in
@@ -29,9 +29,7 @@ BuildRequires: vte-devel
BuildRequires: gnome-doc-utils
BuildRequires: intltool
BuildRequires: libgudev1-devel
-BuildRequires: libXxf86vm-devel
BuildRequires: libXrandr-devel
-BuildRequires: gnome-desktop3-devel
BuildRequires: lcms2-devel
BuildRequires: cups-devel
BuildRequires: sane-backends-devel
@@ -64,6 +62,8 @@ done
rm -f $RPM_BUILD_ROOT%{_libdir}/control-center-1/panels/*.a
rm -f $RPM_BUILD_ROOT%{_libdir}/control-center-1/panels/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%find_lang %name --with-gnome
@@ -113,6 +113,12 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &> /dev/null || :
%{_datadir}/GConf/gsettings/org.gnome.color-manager.gschema.migrate
%{_datadir}/dbus-1/interfaces/org.gnome.ColorManager.xml
%{_libdir}/control-center-1/panels/*.so
+%{_includedir}/libcolor-glib/*.h
+%{_libdir}/libcolor-glib.so
+%{_libdir}/libcolor-glib.so.1
+%{_libdir}/libcolor-glib.so.1.0.0
+%{_libdir}/pkgconfig/libcolor-glib.pc
+%{_datadir}/gtk-doc/html/libcolor-glib
%changelog
* #LONGDATE# Richard Hughes <richard hughsie com> #VERSION#-0.#BUILD##ALPHATAG#
diff --git a/docs/api/libcolor-glib-docs.sgml b/docs/api/libcolor-glib-docs.sgml
index 524e05d..ef6ef59 100644
--- a/docs/api/libcolor-glib-docs.sgml
+++ b/docs/api/libcolor-glib-docs.sgml
@@ -36,7 +36,8 @@
<xi:include href="xml/gcm-client.xml"/>
-->
<xi:include href="xml/gcm-sensor-dummy.xml"/>
- <xi:include href="xml/gcm-xserver.xml"/>
+ <xi:include href="xml/gcm-x11-output.xml"/>
+ <xi:include href="xml/gcm-x11-screen.xml"/>
<xi:include href="xml/gcm-edid.xml"/>
<xi:include href="xml/gcm-ddc-control.xml"/>
<xi:include href="xml/gcm-profile.xml"/>
diff --git a/libcolor-glib/Makefile.am b/libcolor-glib/Makefile.am
index 597b2cb..e032d13 100644
--- a/libcolor-glib/Makefile.am
+++ b/libcolor-glib/Makefile.am
@@ -46,7 +46,6 @@ libcolor_glib_include_HEADERS = \
gcm-image.h \
gcm-profile-store.h \
gcm-dmi.h \
- gcm-xserver.h \
gcm-version.h \
$(NULL)
@@ -96,8 +95,10 @@ libcolor_glib_la_SOURCES = \
gcm-usb.h \
gcm-profile-store.c \
gcm-profile-store.h \
- gcm-xserver.c \
- gcm-xserver.h \
+ gcm-x11-output.c \
+ gcm-x11-output.h \
+ gcm-x11-screen.c \
+ gcm-x11-screen.h \
gcm-version.h \
gcm-brightness.c \
gcm-brightness.h \
diff --git a/libcolor-glib/gcm-x11-output.c b/libcolor-glib/gcm-x11-output.c
new file mode 100644
index 0000000..24b20e0
--- /dev/null
+++ b/libcolor-glib/gcm-x11-output.c
@@ -0,0 +1,705 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2008 Soren Sandmann <sandmann redhat com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * SECTION:gcm-x11-output
+ * @short_description: Object to interact with the XServer
+ *
+ * This object talks to the currently running X Server.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/Xatom.h>
+#include <string.h>
+#include <gdk/gdk.h>
+
+#include "gcm-x11-output.h"
+
+#include "egg-debug.h"
+
+static void gcm_x11_output_finalize (GObject *object);
+
+#define GCM_X11_OUTPUT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_X11_OUTPUT, GcmX11OutputPrivate))
+
+/**
+ * GcmX11OutputPrivate:
+ *
+ * Private #GcmX11Output data
+ **/
+struct _GcmX11OutputPrivate
+{
+ gchar *display_name;
+ Display *display;
+ gchar *name;
+ guint id;
+ guint crtc_id;
+ gboolean primary;
+ guint gamma_size;
+ gboolean connected;
+ guint x;
+ guint y;
+ guint width;
+ guint height;
+};
+
+enum {
+ PROP_0,
+ PROP_DISPLAY_NAME,
+ PROP_LAST
+};
+
+G_DEFINE_TYPE (GcmX11Output, gcm_x11_output, G_TYPE_OBJECT)
+
+/**
+ * gcm_x11_output_set_name:
+ **/
+void
+gcm_x11_output_set_display (GcmX11Output *output, gpointer display)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->display = display;
+}
+
+/**
+ * gcm_x11_output_set_name:
+ **/
+void
+gcm_x11_output_set_name (GcmX11Output *output, const gchar *name)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->name = g_strdup (name);
+}
+
+/**
+ * gcm_x11_output_get_name:
+ **/
+const gchar *
+gcm_x11_output_get_name (GcmX11Output *output)
+{
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), NULL);
+ return output->priv->name;
+}
+
+/**
+ * gcm_x11_output_set_id:
+ **/
+void
+gcm_x11_output_set_id (GcmX11Output *output, guint id)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->id = id;
+}
+
+/**
+ * gcm_x11_output_get_id:
+ **/
+guint
+gcm_x11_output_get_id (GcmX11Output *output)
+{
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), 0);
+ return output->priv->id;
+}
+
+/**
+ * gcm_x11_output_set_crtc_id:
+ **/
+void
+gcm_x11_output_set_crtc_id (GcmX11Output *output, guint crtc_id)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->crtc_id = crtc_id;
+}
+
+/**
+ * gcm_x11_output_get_crtc_id:
+ **/
+guint
+gcm_x11_output_get_crtc_id (GcmX11Output *output)
+{
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), 0);
+ return output->priv->crtc_id;
+}
+
+/**
+ * gcm_x11_output_set_gamma_size:
+ **/
+void
+gcm_x11_output_set_gamma_size (GcmX11Output *output, guint gamma_size)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->gamma_size = gamma_size;
+}
+
+/**
+ * gcm_x11_output_get_gamma_size:
+ **/
+guint
+gcm_x11_output_get_gamma_size (GcmX11Output *output)
+{
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), 0);
+ return output->priv->gamma_size;
+}
+
+/**
+ * gcm_x11_output_set_primary:
+ **/
+void
+gcm_x11_output_set_primary (GcmX11Output *output, gboolean primary)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->primary = primary;
+}
+
+/**
+ * gcm_x11_output_get_primary:
+ **/
+gboolean
+gcm_x11_output_get_primary (GcmX11Output *output)
+{
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ return output->priv->primary;
+}
+
+/**
+ * gcm_x11_output_set_connected:
+ **/
+void
+gcm_x11_output_set_connected (GcmX11Output *output, gboolean connected)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->connected = connected;
+}
+
+/**
+ * gcm_x11_output_get_connected:
+ **/
+gboolean
+gcm_x11_output_get_connected (GcmX11Output *output)
+{
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ return output->priv->connected;
+}
+
+/**
+ * gcm_x11_output_set_position:
+ **/
+void
+gcm_x11_output_set_position (GcmX11Output *output, guint x, guint y)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->x = x;
+ output->priv->y = y;
+}
+
+/**
+ * gcm_x11_output_get_position:
+ **/
+void
+gcm_x11_output_get_position (GcmX11Output *output, guint *x, guint *y)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ if (x != NULL)
+ *x = output->priv->x;
+ if (y != NULL)
+ *y = output->priv->y;
+}
+
+/**
+ * gcm_x11_output_set_size:
+ **/
+void
+gcm_x11_output_set_size (GcmX11Output *output, guint width, guint height)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ output->priv->width = width;
+ output->priv->height = height;
+}
+
+/**
+ * gcm_x11_output_get_size:
+ **/
+void
+gcm_x11_output_get_size (GcmX11Output *output, guint *width, guint *height)
+{
+ g_return_if_fail (GCM_IS_X11_OUTPUT (output));
+ if (width != NULL)
+ *width = output->priv->width;
+ if (height != NULL)
+ *height = output->priv->height;
+}
+
+/**
+ * gcm_x11_output_get_property_atom:
+ **/
+static guint8 *
+gcm_x11_output_get_property_atom (GcmX11Output *output, Atom atom, gint *len)
+{
+ guchar *prop;
+ gint actual_format;
+ unsigned long nitems, bytes_after;
+ Atom actual_type;
+ guint8 *result = NULL;
+
+ /* get a property on the output */
+ gdk_error_trap_push ();
+ XRRGetOutputProperty (output->priv->display, output->priv->id, atom,
+ 0, 100, False, False,
+ AnyPropertyType,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, &prop);
+ gdk_flush ();
+ if (gdk_error_trap_pop ())
+ goto out;
+ if (actual_type == XA_INTEGER && actual_format == 8) {
+ result = g_memdup (prop, nitems);
+ if (len)
+ *len = nitems;
+ }
+ XFree (prop);
+out:
+ return result;
+}
+
+/**
+ * gcm_x11_output_get_edid_data:
+ **/
+gboolean
+gcm_x11_output_get_edid_data (GcmX11Output *output, guint8 **data, gsize *length, GError **error)
+{
+ Atom edid_atom;
+ guint8 *result;
+ gint len;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ g_return_val_if_fail (output->priv->display != NULL, FALSE);
+
+ /* get the new name */
+ edid_atom = XInternAtom (output->priv->display, "EDID", FALSE);
+ result = gcm_x11_output_get_property_atom (output, edid_atom, &len);
+
+ /* try harder */
+ if (result == NULL) {
+ edid_atom = XInternAtom (output->priv->display, "EDID_DATA", FALSE);
+ result = gcm_x11_output_get_property_atom (output, edid_atom, &len);
+ }
+
+ /* failed */
+ if (result == NULL) {
+ g_set_error_literal (error, 1, 0, "no edid data");
+ goto out;
+ }
+
+ /* success */
+ if (data != NULL)
+ *data = result;
+ ret = TRUE;
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_output_set_gamma:
+ * @output: a valid %GcmX11Output instance
+ * @error: a %GError, or %NULL
+ *
+ * Sets the gamma ramps for the given output.
+ *
+ * Return value: %TRUE for success.
+ **/
+gboolean
+gcm_x11_output_set_gamma (GcmX11Output *output, guint size, guint16 *red, guint16 *green, guint16 *blue, GError **error)
+{
+ guint copy_size;
+ XRRCrtcGamma *gamma;
+
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ g_return_val_if_fail (output->priv->display != NULL, FALSE);
+ g_return_val_if_fail (red != NULL, FALSE);
+ g_return_val_if_fail (green != NULL, FALSE);
+ g_return_val_if_fail (blue != NULL, FALSE);
+
+ return TRUE;
+
+ if (size != output->priv->gamma_size)
+ return FALSE;
+
+ gamma = XRRAllocGamma (output->priv->gamma_size);
+ copy_size = output->priv->gamma_size * sizeof (guint16);
+ memcpy (gamma->red, red, copy_size);
+ memcpy (gamma->green, green, copy_size);
+ memcpy (gamma->blue, blue, copy_size);
+
+ gdk_error_trap_push ();
+ XRRSetCrtcGamma (output->priv->display, output->priv->crtc_id, gamma);
+ XRRFreeGamma (gamma);
+ gdk_flush ();
+ if (gdk_error_trap_pop ()) {
+ g_set_error_literal (error,
+ GCM_X11_OUTPUT_ERROR, GCM_X11_OUTPUT_ERROR_INTERNAL,
+ "Failed to set gamma");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * gcm_x11_output_get_gamma:
+ **/
+gboolean
+gcm_x11_output_get_gamma (GcmX11Output *output, guint *size, guint16 **red, guint16 **green, guint16 **blue, GError **error)
+{
+ guint copy_size;
+ guint16 *r, *g, *b;
+ XRRCrtcGamma *gamma;
+
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ g_return_val_if_fail (output->priv->display != NULL, FALSE);
+
+ gdk_error_trap_push ();
+ gamma = XRRGetCrtcGamma (output->priv->display, output->priv->crtc_id);
+ gdk_flush ();
+ if (gdk_error_trap_pop () || gamma == NULL) {
+ g_set_error_literal (error,
+ GCM_X11_OUTPUT_ERROR, GCM_X11_OUTPUT_ERROR_INTERNAL,
+ "Failed to get gamma");
+ return FALSE;
+ }
+
+ copy_size = output->priv->gamma_size * sizeof (guint16);
+ if (red != NULL) {
+ r = g_new0 (guint16, output->priv->gamma_size);
+ memcpy (r, gamma->red, copy_size);
+ *red = r;
+ }
+ if (green != NULL) {
+ g = g_new0 (guint16, output->priv->gamma_size);
+ memcpy (g, gamma->green, copy_size);
+ *green = g;
+ }
+ if (blue != NULL) {
+ b = g_new0 (guint16, output->priv->gamma_size);
+ memcpy (b, gamma->blue, copy_size);
+ *blue = b;
+ }
+ if (size)
+ *size = output->priv->gamma_size;
+ XRRFreeGamma (gamma);
+ return TRUE;
+}
+
+
+/**
+ * gcm_x11_output_get_profile_data:
+ *
+ * @x11: a valid %GcmX11Output instance
+ * @data: the data that is returned from the XServer. Free with g_free()
+ * @length: the size of the returned data, or %NULL if you don't care
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Gets the ICC profile data from the specified output.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_output_get_profile_data (GcmX11Output *output, guint8 **data, gsize *length, GError **error)
+{
+ gboolean ret = FALSE;
+ gchar *data_tmp = NULL;
+ gint format;
+ gint rc = -1;
+ gulong bytes_after;
+ gulong nitems = 0;
+ Atom atom;
+ Atom type;
+ GcmX11OutputPrivate *priv = output->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->display, "_ICC_PROFILE", FALSE);
+ rc = XRRGetOutputProperty (priv->display, priv->id,
+ atom, 0, ~0, False, False,
+ AnyPropertyType, &type, &format, &nitems, &bytes_after,
+ (unsigned char **) &data_tmp);
+ egg_debug ("got %i bytes", (guint) nitems);
+ gdk_error_trap_pop ();
+
+ /* did the call fail */
+ if (rc != Success) {
+ g_set_error (error, 1, 0, "failed to get icc profile atom with rc %i", rc);
+ goto out;
+ }
+
+ /* was nothing found */
+ if (nitems == 0) {
+ g_set_error (error, 1, 0, "icc profile atom has not been set");
+ goto out;
+ }
+
+ /* allocate the data using Glib, rather than asking the user to use XFree */
+ *data = g_new0 (guint8, nitems);
+ memcpy (*data, data_tmp, nitems);
+
+ /* copy the length */
+ if (length != NULL)
+ *length = nitems;
+
+ /* success */
+ ret = TRUE;
+out:
+ if (data_tmp != NULL)
+ XFree (data_tmp);
+ return ret;
+}
+
+/**
+ * gcm_x11_output_set_profile:
+ * @x11: a valid %GcmX11Output instance
+ * @filename: the filename of the ICC profile
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Sets the ICC profile data to the specified output.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_output_set_profile (GcmX11Output *output, const gchar *filename, GError **error)
+{
+ gboolean ret;
+ gchar *data = NULL;
+ gsize length;
+
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+
+ egg_debug ("setting output ICC profile atom from %s", filename);
+
+ /* get contents of file */
+ ret = g_file_get_contents (filename, &data, &length, error);
+ if (!ret)
+ goto out;
+
+ /* send to the XServer */
+ ret = gcm_x11_output_set_profile_data (output, (const guint8 *) data, length, error);
+ if (!ret)
+ goto out;
+out:
+ g_free (data);
+ return ret;
+}
+
+/**
+ * gcm_x11_output_set_profile_data:
+ * @x11: a valid %GcmX11Output instance
+ * @data: the data that is to be set to the XServer
+ * @length: the size of the data
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Sets the ICC profile data to the specified output.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_output_set_profile_data (GcmX11Output *output, const guint8 *data, gsize length, GError **error)
+{
+ gboolean ret = FALSE;
+ gint rc;
+ Atom atom = None;
+ GcmX11OutputPrivate *priv = output->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (length != 0, FALSE);
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->display, "_ICC_PROFILE", FALSE);
+ XRRChangeOutputProperty (priv->display, priv->id,
+ atom, XA_CARDINAL, 8,
+ PropModeReplace,
+ (unsigned char*) data, (gint)length);
+ rc = gdk_error_trap_pop ();
+
+ /* did the call fail */
+ if (rc != Success) {
+ g_set_error (error, 1, 0, "failed to set output icc profile atom with rc %i", rc);
+ goto out;
+ }
+
+ /* success */
+ ret = TRUE;
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_output_remove_profile:
+ * @x11: a valid %GcmX11Output instance
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Sets the ICC profile data to the specified output.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_output_remove_profile (GcmX11Output *output, GError **error)
+{
+ gboolean ret = FALSE;
+ gint rc;
+ Atom atom;
+ GcmX11OutputPrivate *priv = output->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->display, "_ICC_PROFILE", FALSE);
+ XRRDeleteOutputProperty (priv->display, priv->id, atom);
+ rc = gdk_error_trap_pop ();
+
+ /* did the call fail */
+ if (rc != Success) {
+ g_set_error (error, 1, 0, "failed to remove output icc profile atom with rc %i", rc);
+ goto out;
+ }
+
+ /* success */
+ ret = TRUE;
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_output_get_property:
+ **/
+static void
+gcm_x11_output_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GcmX11Output *output = GCM_X11_OUTPUT (object);
+ GcmX11OutputPrivate *priv = output->priv;
+
+ switch (prop_id) {
+ case PROP_DISPLAY_NAME:
+ g_value_set_string (value, priv->display_name);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * gcm_x11_output_set_property:
+ **/
+static void
+gcm_x11_output_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GcmX11Output *output = GCM_X11_OUTPUT (object);
+ GcmX11OutputPrivate *priv = output->priv;
+
+ switch (prop_id) {
+ case PROP_DISPLAY_NAME:
+ g_free (priv->display_name);
+ priv->display_name = g_strdup (g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * gcm_x11_output_class_init:
+ **/
+static void
+gcm_x11_output_class_init (GcmX11OutputClass *klass)
+{
+ GParamSpec *pspec;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gcm_x11_output_finalize;
+ object_class->get_property = gcm_x11_output_get_property;
+ object_class->set_property = gcm_x11_output_set_property;
+
+ /**
+ * GcmX11Output:display-name:
+ */
+ pspec = g_param_spec_string ("display-name", NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_DISPLAY_NAME, pspec);
+
+ g_type_class_add_private (klass, sizeof (GcmX11OutputPrivate));
+}
+
+/**
+ * gcm_x11_output_init:
+ **/
+static void
+gcm_x11_output_init (GcmX11Output *output)
+{
+ output->priv = GCM_X11_OUTPUT_GET_PRIVATE (output);
+ output->priv->display_name = NULL;
+}
+
+/**
+ * gcm_x11_output_finalize:
+ **/
+static void
+gcm_x11_output_finalize (GObject *object)
+{
+ GcmX11Output *output = GCM_X11_OUTPUT (object);
+ GcmX11OutputPrivate *priv = output->priv;
+
+ g_free (priv->display_name);
+
+ G_OBJECT_CLASS (gcm_x11_output_parent_class)->finalize (object);
+}
+
+/**
+ * gcm_x11_output_new:
+ *
+ * Return value: a new GcmX11Output object.
+ *
+ * Since: 0.0.1
+ **/
+GcmX11Output *
+gcm_x11_output_new (void)
+{
+ GcmX11Output *output;
+ output = g_object_new (GCM_TYPE_X11_OUTPUT, NULL);
+ return GCM_X11_OUTPUT (output);
+}
+
diff --git a/libcolor-glib/gcm-x11-output.h b/libcolor-glib/gcm-x11-output.h
new file mode 100644
index 0000000..dac019a
--- /dev/null
+++ b/libcolor-glib/gcm-x11-output.h
@@ -0,0 +1,123 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#if !defined (__LIBCOLOR_GLIB_H_INSIDE__) && !defined (LIBCOLOR_GLIB_COMPILATION)
+#error "Only <libcolor-glib.h> can be included directly."
+#endif
+
+#ifndef __GCM_X11_OUTPUT_H
+#define __GCM_X11_OUTPUT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GCM_TYPE_X11_OUTPUT (gcm_x11_output_get_type ())
+#define GCM_X11_OUTPUT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GCM_TYPE_X11_OUTPUT, GcmX11Output))
+#define GCM_IS_X11_OUTPUT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GCM_TYPE_X11_OUTPUT))
+
+#define GCM_X11_OUTPUT_ERROR 1
+#define GCM_X11_OUTPUT_ERROR_INTERNAL 0
+
+typedef struct _GcmX11OutputPrivate GcmX11OutputPrivate;
+typedef struct _GcmX11Output GcmX11Output;
+typedef struct _GcmX11OutputClass GcmX11OutputClass;
+
+struct _GcmX11Output
+{
+ GObject parent;
+ GcmX11OutputPrivate *priv;
+};
+
+struct _GcmX11OutputClass
+{
+ GObjectClass parent_class;
+};
+
+GType gcm_x11_output_get_type (void);
+GcmX11Output *gcm_x11_output_new (void);
+
+void gcm_x11_output_set_display (GcmX11Output *output,
+ gpointer display);
+void gcm_x11_output_set_name (GcmX11Output *output,
+ const gchar *name);
+const gchar *gcm_x11_output_get_name (GcmX11Output *output);
+void gcm_x11_output_set_id (GcmX11Output *output,
+ guint id);
+guint gcm_x11_output_get_id (GcmX11Output *output);
+void gcm_x11_output_set_crtc_id (GcmX11Output *output,
+ guint crtc_id);
+guint gcm_x11_output_get_crtc_id (GcmX11Output *output);
+void gcm_x11_output_set_gamma_size (GcmX11Output *output,
+ guint gamma_size);
+guint gcm_x11_output_get_gamma_size (GcmX11Output *output);
+void gcm_x11_output_set_position (GcmX11Output *output,
+ guint x,
+ guint y);
+void gcm_x11_output_get_position (GcmX11Output *output,
+ guint *x,
+ guint *y);
+void gcm_x11_output_set_size (GcmX11Output *output,
+ guint width,
+ guint height);
+void gcm_x11_output_get_size (GcmX11Output *output,
+ guint *width,
+ guint *height);
+void gcm_x11_output_set_primary (GcmX11Output *output,
+ gboolean primary);
+gboolean gcm_x11_output_get_primary (GcmX11Output *output);
+void gcm_x11_output_set_connected (GcmX11Output *output,
+ gboolean connected);
+gboolean gcm_x11_output_get_connected (GcmX11Output *output);
+gboolean gcm_x11_output_get_gamma (GcmX11Output *output,
+ guint *size,
+ guint16 **red,
+ guint16 **green,
+ guint16 **blue,
+ GError **error);
+gboolean gcm_x11_output_set_gamma (GcmX11Output *output,
+ guint size,
+ guint16 *red,
+ guint16 *green,
+ guint16 *blue,
+ GError **error);
+gboolean gcm_x11_output_get_edid_data (GcmX11Output *output,
+ guint8 **data,
+ gsize *length,
+ GError **error);
+gboolean gcm_x11_output_get_profile_data (GcmX11Output *output,
+ guint8 **data,
+ gsize *length,
+ GError **error);
+gboolean gcm_x11_output_set_profile_data (GcmX11Output *output,
+ const guint8 *data,
+ gsize length,
+ GError **error);
+gboolean gcm_x11_output_set_profile (GcmX11Output *output,
+ const gchar *filename,
+ GError **error);
+gboolean gcm_x11_output_remove_profile (GcmX11Output *output,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __GCM_X11_OUTPUT_H */
+
diff --git a/libcolor-glib/gcm-x11-screen.c b/libcolor-glib/gcm-x11-screen.c
new file mode 100644
index 0000000..811a85f
--- /dev/null
+++ b/libcolor-glib/gcm-x11-screen.c
@@ -0,0 +1,747 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2008 Soren Sandmann <sandmann redhat com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * SECTION:gcm-x11-screen
+ * @short_description: Object to interact with the XServer
+ *
+ * This object talks to the currently running X Server.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/Xatom.h>
+
+#include "gcm-x11-screen.h"
+
+#include "egg-debug.h"
+
+static void gcm_x11_screen_finalize (GObject *object);
+
+#define GCM_X11_SCREEN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_X11_SCREEN, GcmX11ScreenPrivate))
+
+/**
+ * GcmX11ScreenPrivate:
+ *
+ * Private #GcmX11Screen data
+ **/
+struct _GcmX11ScreenPrivate
+{
+ GdkScreen *gdk_screen;
+ GdkWindow *gdk_root;
+ Display *xdisplay;
+ Screen *xscreen;
+ Window xroot;
+ guint randr_event_base;
+ guint rr_major_version;
+ guint rr_minor_version;
+ GPtrArray *outputs;
+};
+
+enum {
+ SIGNAL_CHANGED,
+ SIGNAL_LAST
+};
+
+static guint signals[SIGNAL_LAST] = { 0 };
+static gpointer gcm_x11_screen_object = NULL;
+G_DEFINE_TYPE (GcmX11Screen, gcm_x11_screen, G_TYPE_OBJECT)
+
+/**
+ * gcm_x11_screen_on_event_cb:
+ **/
+static GdkFilterReturn
+gcm_x11_screen_on_event_cb (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ GcmX11Screen *screen = data;
+ GcmX11ScreenPrivate *priv = screen->priv;
+ XEvent *e = xevent;
+ gint event_num;
+
+ if (e == NULL)
+ return GDK_FILTER_CONTINUE;
+
+ event_num = e->type - priv->randr_event_base;
+
+ if (event_num == RRScreenChangeNotify) {
+ egg_debug ("emit changed");
+ g_signal_emit (screen, signals[SIGNAL_CHANGED], 0);
+ }
+
+ /* Pass the event on to GTK+ */
+ return GDK_FILTER_CONTINUE;
+}
+
+/**
+ * gcm_x11_screen_refresh:
+ **/
+static gboolean
+gcm_x11_screen_refresh (GcmX11Screen *screen, GError **error)
+{
+ gint i;
+ gboolean connected;
+ gboolean ret = FALSE;
+ GcmX11ScreenPrivate *priv = screen->priv;
+ XRRScreenResources *resources;
+ RROutput rr_output;
+ GcmX11Output *output;
+ XRROutputInfo *output_info;
+ XRRCrtcInfo *crtc_info;
+ gint gamma_size;
+
+ /* clear old outputs */
+ g_ptr_array_set_size (priv->outputs, 0);
+
+ /* get new resources */
+ gdk_error_trap_push ();
+ resources = XRRGetScreenResources (priv->xdisplay, priv->xroot);
+ gdk_flush ();
+ if (gdk_error_trap_pop () || resources == NULL) {
+ g_set_error_literal (error,
+ GCM_X11_SCREEN_ERROR, GCM_X11_SCREEN_ERROR_INTERNAL,
+ "Failed to get X11 resources");
+ goto out;
+ }
+
+ /* add each output */
+ for (i=0; i < resources->noutput; i++) {
+ rr_output = resources->outputs[i];
+
+ /* get information about the output */
+ gdk_error_trap_push ();
+ output_info = XRRGetOutputInfo (priv->xdisplay, resources, rr_output);
+ gdk_flush ();
+ if (gdk_error_trap_pop ()) {
+ egg_warning ("failed to get output info");
+ continue;
+ }
+
+ connected = (output_info->connection == RR_Connected);
+ if (connected && output_info->crtc != 0) {
+
+ /* get crtc info */
+ gdk_error_trap_push ();
+ crtc_info = XRRGetCrtcInfo (priv->xdisplay, resources, output_info->crtc);
+ gdk_flush ();
+ if (gdk_error_trap_pop () || crtc_info == NULL) {
+ egg_warning ("failed to get crtc info for %s", output_info->name);
+ continue;
+ }
+
+ /* get gamma size */
+ gdk_error_trap_push ();
+ gamma_size = XRRGetCrtcGammaSize (priv->xdisplay, output_info->crtc);
+ gdk_flush ();
+ if (gdk_error_trap_pop ()) {
+ egg_warning ("failed to get gamma size");
+ continue;
+ }
+
+ /* create new object and set properties */
+ output = gcm_x11_output_new ();
+ gcm_x11_output_set_name (output, output_info->name);
+ gcm_x11_output_set_display (output, priv->xdisplay);
+ gcm_x11_output_set_id (output, rr_output);
+ gcm_x11_output_set_crtc_id (output, output_info->crtc);
+ gcm_x11_output_set_primary (output, (crtc_info->x == 0 && crtc_info->y == 0));
+ gcm_x11_output_set_gamma_size (output, gamma_size);
+ gcm_x11_output_set_connected (output, connected);
+ gcm_x11_output_set_position (output, crtc_info->x, crtc_info->y);
+ gcm_x11_output_set_size (output, crtc_info->width, crtc_info->height);
+
+ /* add it to the array */
+ g_ptr_array_add (priv->outputs, output);
+
+ /* free client side X resources */
+ XRRFreeCrtcInfo (crtc_info);
+ }
+ XRRFreeOutputInfo (output_info);
+ }
+
+ /* success */
+ ret = TRUE;
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_assign:
+ * @screen: a valid %GcmX11Screen instance
+ * @gdk_screen: a #GdkScreen
+ * @error: a %GError or %NULL
+ *
+ * Assigns a #GdkScreen to this instance.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_screen_assign (GcmX11Screen *screen, GdkScreen *gdk_screen, GError **error)
+{
+ GcmX11ScreenPrivate *priv = screen->priv;
+ Display *dpy;
+ gint event_base;
+ gint ignore;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ /* NULL means default */
+ if (gdk_screen != NULL) {
+ priv->gdk_screen = gdk_screen;
+ } else {
+ priv->gdk_screen = gdk_screen_get_default ();
+ }
+
+ /* do we even have XRandR? */
+ dpy = GDK_SCREEN_XDISPLAY (priv->gdk_screen);
+ if (!XRRQueryExtension (dpy, &event_base, &ignore)) {
+ g_set_error_literal (error, GCM_X11_SCREEN_ERROR, GCM_X11_SCREEN_ERROR_INTERNAL,
+ "RANDR extension is not present");
+ goto out;
+ }
+
+ priv->gdk_root = gdk_screen_get_root_window (priv->gdk_screen);
+ priv->xroot = gdk_x11_drawable_get_xid (priv->gdk_root);
+ priv->xdisplay = dpy;
+ priv->xscreen = gdk_x11_screen_get_xscreen (priv->gdk_screen);
+ priv->randr_event_base = event_base;
+
+ /* get version */
+ gdk_error_trap_push ();
+ XRRQueryVersion (dpy, (gint*)&priv->rr_major_version, (gint*)&priv->rr_minor_version);
+ gdk_flush ();
+ if (gdk_error_trap_pop ()) {
+ g_set_error_literal (error, GCM_X11_SCREEN_ERROR, GCM_X11_SCREEN_ERROR_INTERNAL,
+ "failed to get RANDR extension version");
+ goto out;
+ }
+
+ /* too small */
+ if (priv->rr_major_version > 1 ||
+ (priv->rr_major_version == 1 && priv->rr_minor_version < 2)) {
+ g_set_error_literal (error, GCM_X11_SCREEN_ERROR, GCM_X11_SCREEN_ERROR_INTERNAL,
+ "RANDR extension is too old (must be at least 1.2)");
+ goto out;
+ }
+
+ /* add filter */
+ gdk_error_trap_push ();
+ XRRSelectInput (priv->xdisplay,
+ priv->xroot,
+ RRScreenChangeNotifyMask);
+ if (gdk_error_trap_pop ()) {
+ egg_warning ("failed to select input");
+ goto out;
+ }
+
+ gdk_x11_register_standard_event_type (gdk_screen_get_display (priv->gdk_screen),
+ event_base, RRNotify + 1);
+
+ gdk_window_add_filter (priv->gdk_root, gcm_x11_screen_on_event_cb, screen);
+
+ /* get resources */
+ ret = gcm_x11_screen_refresh (screen, error);
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_get_outputs:
+ * @screen: a valid %GcmX11Screen instance
+ * @error: a %GError or %NULL
+ *
+ * Gets the list of outputs.
+ *
+ * Return value: A #GPtrArray of #GcmX11Output's. Free with g_ptr_array_unref() when done.
+ *
+ * Since: 0.0.1
+ **/
+GPtrArray *
+gcm_x11_screen_get_outputs (GcmX11Screen *screen, GError **error)
+{
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ /* not set the display */
+ if (priv->gdk_screen == NULL) {
+ g_set_error_literal (error,
+ GCM_X11_SCREEN_ERROR, GCM_X11_SCREEN_ERROR_INTERNAL,
+ "no display set, use gcm_x11_screen_assign()");
+ return NULL;
+ }
+
+ return g_ptr_array_ref (priv->outputs);
+}
+
+/**
+ * gcm_x11_screen_get_output_by_name:
+ * @screen: a valid %GcmX11Screen instance
+ * @name: an output name, e.g. "lvds1"
+ * @error: a %GError or %NULL
+ *
+ * Gets a specified output.
+ *
+ * Return value: A #GcmX11Output, or %NULL if nothing matched.
+ *
+ * Since: 0.0.1
+ **/
+GcmX11Output *
+gcm_x11_screen_get_output_by_name (GcmX11Screen *screen, const gchar *name, GError **error)
+{
+ guint i;
+ GcmX11Output *output;
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ /* not set the display */
+ if (priv->gdk_screen == NULL) {
+ g_set_error_literal (error,
+ GCM_X11_SCREEN_ERROR, GCM_X11_SCREEN_ERROR_INTERNAL,
+ "no display set, use gcm_x11_screen_assign()");
+ return NULL;
+ }
+
+ /* find the output */
+ for (i=0; i<priv->outputs->len; i++) {
+ output = g_ptr_array_index (priv->outputs, i);
+ if (g_strcmp0 (gcm_x11_output_get_name (output), name) == 0)
+ return g_object_ref (output);
+ }
+ g_set_error_literal (error,
+ GCM_X11_SCREEN_ERROR, GCM_X11_SCREEN_ERROR_INTERNAL,
+ "no output with that name");
+ return NULL;
+}
+
+/**
+ * gcm_x11_screen_get_profile_data:
+ * @x11: a valid %GcmX11Screen instance
+ * @data: the data that is returned from the XServer. Free with g_free()
+ * @length: the size of the returned data, or %NULL if you don't care
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Gets the ICC profile data from the XServer.
+ *
+ * Return value: %TRUE for success.
+ **/
+gboolean
+gcm_x11_screen_get_profile_data (GcmX11Screen *screen, guint8 **data, gsize *length, GError **error)
+{
+ gboolean ret = FALSE;
+ gchar *data_tmp = NULL;
+ gint format;
+ gint rc;
+ gulong bytes_after;
+ gulong nitems;
+ Atom atom = None;
+ Atom type;
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->xdisplay, "_ICC_PROFILE", FALSE);
+ rc = XGetWindowProperty (priv->xdisplay, priv->xroot, atom, 0, G_MAXLONG, False, XA_CARDINAL,
+ &type, &format, &nitems, &bytes_after, (void*) &data_tmp);
+ gdk_error_trap_pop ();
+
+ /* did the call fail */
+ if (rc != Success) {
+ g_set_error (error, 1, 0, "failed to get icc profile atom with rc %i", rc);
+ goto out;
+ }
+
+ /* was nothing found */
+ if (nitems == 0) {
+ g_set_error (error, 1, 0, "atom has not been set");
+ goto out;
+ }
+
+ /* allocate the data using Glib, rather than asking the user to use XFree */
+ *data = g_memdup (data_tmp, nitems);
+
+ /* copy the length */
+ if (length != NULL)
+ *length = nitems;
+
+ /* success */
+ ret = TRUE;
+out:
+ if (data_tmp != NULL)
+ XFree (data_tmp);
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_set_profile:
+ * @x11: a valid %GcmX11Screen instance
+ * @filename: the filename of the ICC profile
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Sets the ICC profile data to the XServer.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_screen_set_profile (GcmX11Screen *screen, const gchar *filename, GError **error)
+{
+ gboolean ret;
+ gchar *data = NULL;
+ gsize length;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+
+ egg_debug ("setting root window ICC profile atom from %s", filename);
+
+ /* get contents of file */
+ ret = g_file_get_contents (filename, &data, &length, error);
+ if (!ret)
+ goto out;
+
+ /* send to the XServer */
+ ret = gcm_x11_screen_set_profile_data (screen, (const guint8 *) data, length, error);
+ if (!ret)
+ goto out;
+out:
+ g_free (data);
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_set_profile_data:
+ * @x11: a valid %GcmX11Screen instance
+ * @data: the data that is to be set to the XServer
+ * @length: the size of the data
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Sets the ICC profile data to the XServer.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_screen_set_profile_data (GcmX11Screen *screen, const guint8 *data, gsize length, GError **error)
+{
+ gboolean ret = FALSE;
+ gint rc;
+ Atom atom = None;
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (length != 0, FALSE);
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->xdisplay, "_ICC_PROFILE", FALSE);
+ rc = XChangeProperty (priv->xdisplay, priv->xroot, atom, XA_CARDINAL, 8, PropModeReplace, (unsigned char*) data, length);
+ gdk_error_trap_pop ();
+
+ /* for some reason this fails with BadRequest, but actually sets the value */
+ if (rc == BadRequest)
+ rc = Success;
+
+ /* did the call fail */
+ if (rc != Success) {
+ g_set_error (error, 1, 0, "failed to set icc profile atom with rc %i", rc);
+ goto out;
+ }
+
+ /* success */
+ ret = TRUE;
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_set_protocol_version:
+ * @x11: a valid %GcmX11Screen instance
+ * @major: the major version
+ * @minor: the minor version
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Sets the ICC Profiles in X supported version to the XServer.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_screen_set_protocol_version (GcmX11Screen *screen, guint major, guint minor, GError **error)
+{
+ gboolean ret = FALSE;
+ gint rc;
+ Atom atom = None;
+ guint data;
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+
+ /* get the atom data */
+ data = major * 100 + minor * 1;
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->xdisplay, "_ICC_PROFILE_IN_X_VERSION", FALSE);
+ rc = XChangeProperty (priv->xdisplay, priv->xroot, atom, XA_CARDINAL, 8, PropModeReplace, (unsigned char*) &data, 1);
+ gdk_error_trap_pop ();
+
+ /* for some reason this fails with BadRequest, but actually sets the value */
+ if (rc == BadRequest)
+ rc = Success;
+
+ /* did the call fail */
+ if (rc != Success) {
+ g_set_error (error, 1, 0, "failed to set icc profile atom with rc %i", rc);
+ goto out;
+ }
+
+ /* success */
+ ret = TRUE;
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_remove_protocol_version:
+ * @x11: a valid %GcmX11Screen instance
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Removes the ICC profile version data from the XServer.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_screen_remove_protocol_version (GcmX11Screen *screen, GError **error)
+{
+ Atom atom = None;
+ gint rc;
+ gboolean ret = TRUE;
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+
+ egg_debug ("removing root window ICC profile atom");
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->xdisplay, "_ICC_PROFILE_IN_X_VERSION", FALSE);
+ rc = XDeleteProperty(priv->xdisplay, priv->xroot, atom);
+ gdk_error_trap_pop ();
+
+ /* this fails with BadRequest if the atom was not set */
+ if (rc == BadRequest)
+ rc = Success;
+
+ /* did the call fail */
+ if (rc != Success) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "failed to delete root window atom with rc %i", rc);
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_get_protocol_version:
+ *
+ * @x11: a valid %GcmX11Screen instance
+ * @major: the major version
+ * @minor: the minor version
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Gets the ICC profile data from the XServer.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_screen_get_protocol_version (GcmX11Screen *screen, guint *major, guint *minor, GError **error)
+{
+ gboolean ret = FALSE;
+ gchar *data_tmp;
+ gint format;
+ gint rc;
+ gulong bytes_after;
+ gulong nitems;
+ Atom atom = None;
+ Atom type;
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+ g_return_val_if_fail (major != NULL, FALSE);
+ g_return_val_if_fail (minor != NULL, FALSE);
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->xdisplay, "_ICC_PROFILE_IN_X_VERSION", FALSE);
+ rc = XGetWindowProperty (priv->xdisplay, priv->xroot, atom, 0, G_MAXLONG, False, XA_CARDINAL,
+ &type, &format, &nitems, &bytes_after, (unsigned char **) &data_tmp);
+ gdk_error_trap_pop ();
+
+ /* did the call fail */
+ if (rc != Success) {
+ g_set_error (error, 1, 0, "failed to get atom with rc %i", rc);
+ goto out;
+ }
+
+ /* was nothing found */
+ if (nitems == 0) {
+ g_set_error (error, 1, 0, "icc profile atom has not been set");
+ goto out;
+ }
+
+ /* set total */
+ *major = (guint) data_tmp[0] / 100;
+ *minor = (guint) data_tmp[0] % 100;
+
+ /* success */
+ ret = TRUE;
+out:
+ if (data_tmp != NULL)
+ XFree (data_tmp);
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_remove_profile:
+ * @x11: a valid %GcmX11Screen instance
+ * @error: a %GError that is set in the result of an error, or %NULL
+ *
+ * Removes the ICC profile data from the XServer.
+ *
+ * Return value: %TRUE for success.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_x11_screen_remove_profile (GcmX11Screen *screen, GError **error)
+{
+ Atom atom = None;
+ gint rc;
+ gboolean ret = TRUE;
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ g_return_val_if_fail (GCM_IS_X11_SCREEN (screen), FALSE);
+
+ egg_debug ("removing root window ICC profile atom");
+
+ /* get the value */
+ gdk_error_trap_push ();
+ atom = XInternAtom (priv->xdisplay, "_ICC_PROFILE", FALSE);
+ rc = XDeleteProperty (priv->xdisplay, priv->xroot, atom);
+ gdk_error_trap_pop ();
+
+ /* this fails with BadRequest if the atom was not set */
+ if (rc == BadRequest)
+ rc = Success;
+
+ /* did the call fail */
+ if (rc != Success) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "failed to delete root window atom with rc %i", rc);
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/**
+ * gcm_x11_screen_class_init:
+ **/
+static void
+gcm_x11_screen_class_init (GcmX11ScreenClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gcm_x11_screen_finalize;
+
+ /**
+ * GcmX11Screen::changed:
+ **/
+ signals[SIGNAL_CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcmX11ScreenClass, changed),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private (klass, sizeof (GcmX11ScreenPrivate));
+}
+
+/**
+ * gcm_x11_screen_init:
+ **/
+static void
+gcm_x11_screen_init (GcmX11Screen *screen)
+{
+ screen->priv = GCM_X11_SCREEN_GET_PRIVATE (screen);
+ screen->priv->outputs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+}
+
+/**
+ * gcm_x11_screen_finalize:
+ **/
+static void
+gcm_x11_screen_finalize (GObject *object)
+{
+ GcmX11Screen *screen = GCM_X11_SCREEN (object);
+ GcmX11ScreenPrivate *priv = screen->priv;
+
+ g_ptr_array_unref (screen->priv->outputs);
+ gdk_window_remove_filter (priv->gdk_root, gcm_x11_screen_on_event_cb, screen);
+
+ G_OBJECT_CLASS (gcm_x11_screen_parent_class)->finalize (object);
+}
+
+/**
+ * gcm_x11_screen_new:
+ *
+ * Return value: a new #GcmX11Screen object.
+ *
+ * Since: 0.0.1
+ **/
+GcmX11Screen *
+gcm_x11_screen_new (void)
+{
+ if (gcm_x11_screen_object != NULL) {
+ g_object_ref (gcm_x11_screen_object);
+ } else {
+ gcm_x11_screen_object = g_object_new (GCM_TYPE_X11_SCREEN, NULL);
+ g_object_add_weak_pointer (gcm_x11_screen_object, &gcm_x11_screen_object);
+ }
+ return GCM_X11_SCREEN (gcm_x11_screen_object);
+}
+
diff --git a/libcolor-glib/gcm-x11-screen.h b/libcolor-glib/gcm-x11-screen.h
new file mode 100644
index 0000000..52f7e54
--- /dev/null
+++ b/libcolor-glib/gcm-x11-screen.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#if !defined (__LIBCOLOR_GLIB_H_INSIDE__) && !defined (LIBCOLOR_GLIB_COMPILATION)
+#error "Only <libcolor-glib.h> can be included directly."
+#endif
+
+#ifndef __GCM_X11_SCREEN_H
+#define __GCM_X11_SCREEN_H
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+
+#include "gcm-x11-output.h"
+
+G_BEGIN_DECLS
+
+#define GCM_TYPE_X11_SCREEN (gcm_x11_screen_get_type ())
+#define GCM_X11_SCREEN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GCM_TYPE_X11_SCREEN, GcmX11Screen))
+#define GCM_IS_X11_SCREEN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GCM_TYPE_X11_SCREEN))
+
+#define GCM_X11_SCREEN_ERROR 1
+#define GCM_X11_SCREEN_ERROR_INTERNAL 0
+
+typedef struct _GcmX11ScreenPrivate GcmX11ScreenPrivate;
+typedef struct _GcmX11Screen GcmX11Screen;
+typedef struct _GcmX11ScreenClass GcmX11ScreenClass;
+
+struct _GcmX11Screen
+{
+ GObject parent;
+ GcmX11ScreenPrivate *priv;
+};
+
+struct _GcmX11ScreenClass
+{
+ GObjectClass parent_class;
+ void (* changed) (GcmX11Screen *screen);
+};
+
+GType gcm_x11_screen_get_type (void);
+GcmX11Screen *gcm_x11_screen_new (void);
+
+gboolean gcm_x11_screen_assign (GcmX11Screen *screen,
+ GdkScreen *gdk_screen,
+ GError **error);
+GPtrArray *gcm_x11_screen_get_outputs (GcmX11Screen *screen,
+ GError **error);
+GcmX11Output *gcm_x11_screen_get_output_by_name (GcmX11Screen *screen,
+ const gchar *name,
+ GError **error);
+gboolean gcm_x11_screen_get_profile_data (GcmX11Screen *screen,
+ guint8 **data,
+ gsize *length,
+ GError **error);
+gboolean gcm_x11_screen_set_profile_data (GcmX11Screen *screen,
+ const guint8 *data,
+ gsize length,
+ GError **error);
+gboolean gcm_x11_screen_set_profile (GcmX11Screen *screen,
+ const gchar *filename,
+ GError **error);
+gboolean gcm_x11_screen_remove_profile (GcmX11Screen *screen,
+ GError **error);
+gboolean gcm_x11_screen_set_protocol_version (GcmX11Screen *screen,
+ guint major,
+ guint minor,
+ GError **error);
+gboolean gcm_x11_screen_remove_protocol_version (GcmX11Screen *screen,
+ GError **error);
+gboolean gcm_x11_screen_get_protocol_version (GcmX11Screen *screen,
+ guint *major,
+ guint *minor,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __GCM_X11_SCREEN_H */
+
diff --git a/libcolor-glib/libcolor-glib.h b/libcolor-glib/libcolor-glib.h
index 8cdeecb..6f66ecb 100644
--- a/libcolor-glib/libcolor-glib.h
+++ b/libcolor-glib/libcolor-glib.h
@@ -43,7 +43,8 @@
#include <gcm-enum.h>
#include <gcm-clut.h>
#include <gcm-dmi.h>
-#include <gcm-xserver.h>
+#include <gcm-x11-screen.h>
+#include <gcm-x11-output.h>
#include <gcm-brightness.h>
#include <gcm-profile-store.h>
#include <gcm-usb.h>
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b5590d..59bff3d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,7 +2,6 @@ INCLUDES = \
$(GLIB_CFLAGS) \
$(X11_CFLAGS) \
$(GTK_CFLAGS) \
- $(GNOMEDESKTOP_CFLAGS) \
$(VTE_CFLAGS) \
$(XORG_CFLAGS) \
$(CUPS_CFLAGS) \
@@ -14,7 +13,6 @@ INCLUDES = \
$(CANBERRA_CFLAGS) \
$(CONTROL_CENTER_CFLAGS) \
-DG_UDEV_API_IS_SUBJECT_TO_CHANGE \
- -DGNOME_DESKTOP_USE_UNSTABLE_API \
$(GUDEV_CFLAGS) \
-I$(top_srcdir)/libcolor-glib \
-DLIBCOLOR_GLIB_COMPILATION \
@@ -40,8 +38,6 @@ noinst_LIBRARIES = libgcmshared.a
libgcmshared_a_SOURCES = \
egg-debug.c \
egg-debug.h \
- gcm-screen.c \
- gcm-screen.h \
gcm-exif.c \
gcm-exif.h \
gcm-print.c \
@@ -119,7 +115,6 @@ gcm_inspect_LDADD = \
libgcmshared.a \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
@@ -138,7 +133,6 @@ gcm_apply_LDADD = \
libgcmshared.a \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
@@ -157,7 +151,6 @@ gcm_import_LDADD = \
libgcmshared.a \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
@@ -178,7 +171,6 @@ gcm_viewer_LDADD = \
libgcmshared.a \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(VTE_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
@@ -200,7 +192,6 @@ gcm_picker_LDADD = \
libgcmshared.a \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(VTE_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
@@ -223,7 +214,6 @@ gcm_session_LDADD = \
libgcmshared.a \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
@@ -249,7 +239,6 @@ libcolor_la_SOURCES = \
libcolor_la_LIBADD = \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
@@ -281,7 +270,6 @@ gcm_self_test_LDADD = \
libgcmshared.a \
$(GLIB_LIBS) \
$(X11_LIBS) \
- $(GNOMEDESKTOP_LIBS) \
$(GUDEV_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
diff --git a/src/gcm-calibrate-argyll.c b/src/gcm-calibrate-argyll.c
index 52b13ea..e0947d4 100644
--- a/src/gcm-calibrate-argyll.c
+++ b/src/gcm-calibrate-argyll.c
@@ -43,7 +43,7 @@
#include "gcm-calibrate-argyll.h"
#include "gcm-sensor-client.h"
#include "gcm-utils.h"
-#include "gcm-screen.h"
+#include "gcm-x11-screen.h"
#include "gcm-print.h"
#include "gcm-xyz.h"
#include "gcm-calibrate-dialog.h"
@@ -79,7 +79,7 @@ struct _GcmCalibrateArgyllPrivate
GcmCalibrateDialog *calibrate_dialog;
pid_t child_pid;
GtkResponseType response;
- GcmScreen *screen;
+ GcmX11Screen *screen;
glong vte_previous_row;
glong vte_previous_col;
gboolean already_on_window;
@@ -417,7 +417,7 @@ gcm_calibrate_argyll_display_neutralise (GcmCalibrateArgyll *calibrate_argyll, G
gchar kind;
gchar *command = NULL;
gchar **argv = NULL;
- GnomeRROutput *output;
+ GcmX11Output *output;
GPtrArray *array = NULL;
gchar *basename = NULL;
gchar *output_name = NULL;
@@ -445,7 +445,7 @@ gcm_calibrate_argyll_display_neutralise (GcmCalibrateArgyll *calibrate_argyll, G
}
/* get the device */
- output = gcm_screen_get_output_by_name (priv->screen, output_name, error);
+ output = gcm_x11_screen_get_output_by_name (priv->screen, output_name, error);
if (output == NULL) {
ret = FALSE;
goto out;
@@ -2968,7 +2968,7 @@ gcm_calibrate_argyll_init (GcmCalibrateArgyll *calibrate_argyll)
G_CALLBACK (gcm_calibrate_argyll_response_cb), calibrate_argyll);
/* get screen */
- calibrate_argyll->priv->screen = gcm_screen_new ();
+ calibrate_argyll->priv->screen = gcm_x11_screen_new ();
/* add vte widget */
#ifdef HAVE_VTE
diff --git a/src/gcm-client.c b/src/gcm-client.c
index af9c92b..a0272bf 100644
--- a/src/gcm-client.c
+++ b/src/gcm-client.c
@@ -32,13 +32,13 @@
#include <glib/gi18n.h>
#include <glib-object.h>
#include <gudev/gudev.h>
-#include <libgnomeui/gnome-rr.h>
#include <cups/cups.h>
#ifdef HAVE_SANE
#include <sane/sane.h>
#endif
+#include "gcm-x11-screen.h"
#include "gcm-client.h"
#include "gcm-device-xrandr.h"
#include "gcm-device-udev.h"
@@ -47,7 +47,7 @@
#include "gcm-device-sane.h"
#endif
#include "gcm-device-virtual.h"
-#include "gcm-screen.h"
+#include "gcm-x11-screen.h"
#include "gcm-utils.h"
#include "egg-debug.h"
@@ -56,7 +56,7 @@ static void gcm_client_finalize (GObject *object);
#define GCM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_CLIENT, GcmClientPrivate))
-static void gcm_client_xrandr_add (GcmClient *client, GnomeRROutput *output);
+static void gcm_client_xrandr_add (GcmClient *client, GcmX11Output *output);
#ifdef HAVE_SANE
static gboolean gcm_client_coldplug_devices_sane (GcmClient *client, GError **error);
@@ -74,7 +74,7 @@ struct _GcmClientPrivate
GPtrArray *array;
GUdevClient *gudev_client;
GSettings *settings;
- GcmScreen *screen;
+ GcmX11Screen *screen;
http_t *http;
gboolean loading;
guint loading_refcount;
@@ -590,13 +590,12 @@ gcm_client_get_device_by_window (GcmClient *client, GdkWindow *window)
gfloat covered_max = 0.0f;
gint window_width, window_height;
gint window_x, window_y;
- gint x, y;
+ guint x, y;
guint i;
- guint len = 0;
guint width, height;
- GnomeRRMode *mode;
- GnomeRROutput *output_best = NULL;
- GnomeRROutput **outputs;
+ GcmX11Output *output;
+ GcmX11Output *output_best = NULL;
+ GPtrArray *outputs;
GcmDevice *device = NULL;
/* get the window parameters, in root co-ordinates */
@@ -604,27 +603,22 @@ gcm_client_get_device_by_window (GcmClient *client, GdkWindow *window)
gdk_drawable_get_size (GDK_DRAWABLE(window), &window_width, &window_height);
/* get list of updates */
- outputs = gcm_screen_get_outputs (client->priv->screen, NULL);
+ outputs = gcm_x11_screen_get_outputs (client->priv->screen, NULL);
if (outputs == NULL)
goto out;
- /* find length */
- for (i=0; outputs[i] != NULL; i++)
- len++;
-
/* go through each option */
- for (i=0; i<len; i++) {
+ for (i=0; i<outputs->len; i++) {
/* not interesting */
- if (!gnome_rr_output_is_connected (outputs[i]))
+ output = g_ptr_array_index (outputs, i);
+ if (!gcm_x11_output_get_connected (output))
continue;
/* get details about the output */
- gnome_rr_output_get_position (outputs[i], &x, &y);
- mode = gnome_rr_output_get_current_mode (outputs[i]);
- width = gnome_rr_mode_get_width (mode);
- height = gnome_rr_mode_get_height (mode);
- egg_debug ("%s: %ix%i -> %ix%i (%ix%i -> %ix%i)", gnome_rr_output_get_name (outputs[i]),
+ gcm_x11_output_get_position (output, &x, &y);
+ gcm_x11_output_get_size (output, &width, &height);
+ egg_debug ("%s: %ix%i -> %ix%i (%ix%i -> %ix%i)", gcm_x11_output_get_name (output),
x, y, x+width, y+height,
window_x, window_y, window_x+window_width, window_y+window_height);
@@ -634,7 +628,7 @@ gcm_client_get_device_by_window (GcmClient *client, GdkWindow *window)
/* keep a running total of which one is best */
if (covered > 0.01f && covered > covered_max) {
- output_best = outputs[i];
+ output_best = output;
/* optimize */
if (covered > 0.99) {
@@ -644,10 +638,12 @@ gcm_client_get_device_by_window (GcmClient *client, GdkWindow *window)
/* keep looking */
covered_max = covered;
- egg_debug ("personal best of %f for %s", covered, gnome_rr_output_get_name (output_best));
+ egg_debug ("personal best of %f for %s", covered, gcm_x11_output_get_name (output_best));
}
}
out:
+ if (outputs != NULL)
+ g_ptr_array_unref (outputs);
/* if we found an output, get the device */
if (output_best != NULL) {
GcmDevice *device_tmp;
@@ -663,16 +659,16 @@ out:
* gcm_client_xrandr_add:
**/
static void
-gcm_client_xrandr_add (GcmClient *client, GnomeRROutput *output)
+gcm_client_xrandr_add (GcmClient *client, GcmX11Output *output)
{
gboolean ret;
GError *error = NULL;
GcmDevice *device = NULL;
/* if nothing connected then ignore */
- ret = gnome_rr_output_is_connected (output);
+ ret = gcm_x11_output_get_connected (output);
if (!ret) {
- egg_debug ("%s is not connected", gnome_rr_output_get_name (output));
+ egg_debug ("%s is not connected", gcm_x11_output_get_name (output));
goto out;
}
@@ -703,20 +699,32 @@ out:
static gboolean
gcm_client_coldplug_devices_xrandr (GcmClient *client, GError **error)
{
- GnomeRROutput **outputs;
+ GcmX11Output *output;
+ GPtrArray *outputs = NULL;
guint i;
+ gboolean ret;
GcmClientPrivate *priv = client->priv;
- outputs = gcm_screen_get_outputs (priv->screen, error);
- if (outputs == NULL)
- return FALSE;
- for (i=0; outputs[i] != NULL; i++)
- gcm_client_xrandr_add (client, outputs[i]);
+ /* use the default screen */
+ ret = gcm_x11_screen_assign (priv->screen, NULL, error);
+ if (!ret)
+ goto out;
+ outputs = gcm_x11_screen_get_outputs (priv->screen, error);
+ if (outputs == NULL) {
+ ret = FALSE;
+ goto out;
+ }
- /* inform the UI */
+ /* add each device */
+ for (i=0; i<outputs->len; i++) {
+ output = g_ptr_array_index (outputs, i);
+ gcm_client_xrandr_add (client, output);
+ }
+out:
+ if (outputs != NULL)
+ g_ptr_array_unref (outputs);
gcm_client_done_loading (client);
-
- return TRUE;
+ return ret;
}
/**
@@ -1403,17 +1411,21 @@ gcm_client_set_property (GObject *object, guint prop_id, const GValue *value, GP
* gcm_client_randr_event_cb:
**/
static void
-gcm_client_randr_event_cb (GcmScreen *screen, GcmClient *client)
+gcm_client_randr_event_cb (GcmX11Screen *screen, GcmClient *client)
{
- GnomeRROutput **outputs;
+ GPtrArray *outputs;
+ GcmX11Output *output;
guint i;
egg_debug ("screens may have changed");
/* replug devices */
- outputs = gcm_screen_get_outputs (screen, NULL);
- for (i=0; outputs[i] != NULL; i++)
- gcm_client_xrandr_add (client, outputs[i]);
+ outputs = gcm_x11_screen_get_outputs (screen, NULL);
+ for (i=0; i<outputs->len; i++) {
+ output = g_ptr_array_index (outputs, i);
+ gcm_client_xrandr_add (client, output);
+ }
+ g_ptr_array_unref (outputs);
}
/**
@@ -1501,8 +1513,8 @@ gcm_client_init (GcmClient *client)
client->priv->init_sane = FALSE;
client->priv->settings = g_settings_new (GCM_SETTINGS_SCHEMA);
client->priv->array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
- client->priv->screen = gcm_screen_new ();
- g_signal_connect (client->priv->screen, "outputs-changed",
+ client->priv->screen = gcm_x11_screen_new ();
+ g_signal_connect (client->priv->screen, "changed",
G_CALLBACK (gcm_client_randr_event_cb), client);
/* use GUdev to find devices */
diff --git a/src/gcm-device-xrandr.c b/src/gcm-device-xrandr.c
index b7457df..f87ad73 100644
--- a/src/gcm-device-xrandr.c
+++ b/src/gcm-device-xrandr.c
@@ -24,18 +24,17 @@
#include <glib-object.h>
#include <glib/gi18n.h>
#include <math.h>
-#include <libgnomeui/gnome-rr.h>
#include <X11/extensions/Xrandr.h>
-#include <X11/extensions/xf86vmode.h>
#include <gdk/gdkx.h>
#include "gcm-device-xrandr.h"
#include "gcm-edid.h"
#include "gcm-dmi.h"
#include "gcm-utils.h"
-#include "gcm-xserver.h"
-#include "gcm-screen.h"
+#include "gcm-x11-screen.h"
#include "gcm-clut.h"
+#include "gcm-x11-output.h"
+#include "gcm-x11-screen.h"
#include "egg-debug.h"
@@ -57,16 +56,13 @@ struct _GcmDeviceXrandrPrivate
GcmEdid *edid;
GcmDmi *dmi;
GSettings *settings;
- GcmXserver *xserver;
- GcmScreen *screen;
- gboolean xrandr_fallback;
+ GcmX11Screen *screen;
gboolean remove_atom;
};
enum {
PROP_0,
PROP_NATIVE_DEVICE,
- PROP_XRANDR_FALLBACK,
PROP_EISA_ID,
PROP_EDID_MD5,
PROP_LAST
@@ -105,21 +101,12 @@ gcm_device_xrandr_get_edid_md5 (GcmDeviceXrandr *device_xrandr)
}
/**
- * gcm_device_xrandr_get_fallback:
- **/
-gboolean
-gcm_device_xrandr_get_fallback (GcmDeviceXrandr *device_xrandr)
-{
- return device_xrandr->priv->xrandr_fallback;
-}
-
-/**
* gcm_device_xrandr_get_output_name:
*
* Return value: the output name, free with g_free().
**/
static gchar *
-gcm_device_xrandr_get_output_name (GcmDeviceXrandr *device_xrandr, GnomeRROutput *output)
+gcm_device_xrandr_get_output_name (GcmDeviceXrandr *device_xrandr, GcmX11Output *output)
{
const gchar *output_name;
const gchar *name;
@@ -134,12 +121,12 @@ gcm_device_xrandr_get_output_name (GcmDeviceXrandr *device_xrandr, GnomeRROutput
string = g_string_new ("");
/* if nothing connected then fall back to the connector name */
- ret = gnome_rr_output_is_connected (output);
+ ret = gcm_x11_output_get_connected (output);
if (!ret)
goto out;
/* this is an internal panel, use the DMI data */
- output_name = gnome_rr_output_get_name (output);
+ output_name = gcm_x11_output_get_name (output);
ret = gcm_utils_output_is_lcd_internal (output_name);
if (ret) {
/* find the machine details */
@@ -187,7 +174,7 @@ out:
* gcm_device_xrandr_get_id_for_xrandr_device:
**/
static gchar *
-gcm_device_xrandr_get_id_for_xrandr_device (GcmDeviceXrandr *device_xrandr, GnomeRROutput *output)
+gcm_device_xrandr_get_id_for_xrandr_device (GcmDeviceXrandr *device_xrandr, GcmX11Output *output)
{
const gchar *output_name;
const gchar *name;
@@ -202,7 +189,7 @@ gcm_device_xrandr_get_id_for_xrandr_device (GcmDeviceXrandr *device_xrandr, Gnom
string = g_string_new ("xrandr");
/* if nothing connected then fall back to the connector name */
- ret = gnome_rr_output_is_connected (output);
+ ret = gcm_x11_output_get_connected (output);
if (!ret)
goto out;
@@ -222,11 +209,11 @@ gcm_device_xrandr_get_id_for_xrandr_device (GcmDeviceXrandr *device_xrandr, Gnom
out:
/* fallback to the output name */
if (string->len == 6) {
- output_name = gnome_rr_output_get_name (output);
+ output_name = gcm_x11_output_get_name (output);
ret = gcm_utils_output_is_lcd_internal (output_name);
if (ret)
output_name = "LVDS";
- g_string_append (string, output_name);
+ g_string_append_printf (string, "_%s", output_name);
}
/* replace unsafe chars */
@@ -238,7 +225,7 @@ out:
* gcm_device_xrandr_set_from_output:
**/
gboolean
-gcm_device_xrandr_set_from_output (GcmDevice *device, GnomeRROutput *output, GError **error)
+gcm_device_xrandr_set_from_output (GcmDevice *device, GcmX11Output *output, GError **error)
{
gchar *title = NULL;
gchar *id = NULL;
@@ -248,12 +235,13 @@ gcm_device_xrandr_set_from_output (GcmDevice *device, GnomeRROutput *output, GEr
const gchar *serial;
const gchar *manufacturer;
const gchar *model;
- const guint8 *data;
+ guint8 *data = NULL;
+ gsize length;
GcmDeviceXrandrPrivate *priv = GCM_DEVICE_XRANDR(device)->priv;
- /* parse the EDID to get a crtc-specific name, not an output specific name */
- data = gnome_rr_output_get_edid_data (output);
- if (data != NULL) {
+ /* parse the EDID to get a output specific name */
+ ret = gcm_x11_output_get_edid_data (output, &data, &length, NULL);
+ if (ret) {
ret = gcm_edid_parse (priv->edid, data, NULL);
if (!ret) {
g_set_error (error, 1, 0, "failed to parse edid");
@@ -276,7 +264,7 @@ gcm_device_xrandr_set_from_output (GcmDevice *device, GnomeRROutput *output, GEr
priv->edid_md5 = g_strdup (gcm_edid_get_checksum (priv->edid));
/* refine data if it's missing */
- output_name = gnome_rr_output_get_name (output);
+ output_name = gcm_x11_output_get_name (output);
lcd_internal = gcm_utils_output_is_lcd_internal (output_name);
if (lcd_internal && model == NULL)
model = gcm_dmi_get_version (priv->dmi);
@@ -294,107 +282,29 @@ gcm_device_xrandr_set_from_output (GcmDevice *device, GnomeRROutput *output, GEr
"title", title,
"native-device", output_name,
NULL);
+
+ /* success */
+ ret = TRUE;
out:
+ g_free (data);
g_free (id);
g_free (title);
return ret;
}
-
-/**
- * gcm_device_xrandr_get_gamma_size_fallback:
- **/
-static guint
-gcm_device_xrandr_get_gamma_size_fallback (void)
-{
- guint size;
- Bool rc;
-
- /* this is per-screen, not per output which is less than ideal */
- gdk_error_trap_push ();
- egg_warning ("using PER-SCREEN gamma tables as driver is not XRANDR 1.3 compliant");
- rc = XF86VidModeGetGammaRampSize (GDK_DISPLAY(), gdk_x11_get_default_screen (), (int*) &size);
- gdk_error_trap_pop ();
- if (!rc)
- size = 0;
-
- return size;
-}
-
-/**
- * gcm_device_xrandr_get_gamma_size:
- *
- * Return value: the gamma size, or 0 if error;
- **/
-static guint
-gcm_device_xrandr_get_gamma_size (GcmDeviceXrandr *device_xrandr, GnomeRRCrtc *crtc, GError **error)
-{
- guint id;
- guint size;
- GcmDeviceXrandrPrivate *priv = device_xrandr->priv;
-
- /* use cached value */
- if (priv->gamma_size > 0)
- return priv->gamma_size;
-
- /* get id that X recognizes */
- id = gnome_rr_crtc_get_id (crtc);
-
- /* get the value, and catch errors */
- gdk_error_trap_push ();
- size = XRRGetCrtcGammaSize (GDK_DISPLAY(), id);
- if (gdk_error_trap_pop ())
- size = 0;
-
- /* some drivers support Xrandr 1.2, not 1.3 */
- if (size == 0) {
- priv->xrandr_fallback = TRUE;
- size = gcm_device_xrandr_get_gamma_size_fallback ();
- } else {
- priv->xrandr_fallback = FALSE;
- }
-
- /* no size, or X popped an error */
- if (size == 0) {
- g_set_error_literal (error, 1, 0, "failed to get gamma size");
- goto out;
- }
-
- /* save value as this will not change */
- priv->gamma_size = size;
-out:
- return size;
-}
-
-/**
- * gcm_device_xrandr_apply_fallback:
- **/
-static gboolean
-gcm_device_xrandr_apply_fallback (XRRCrtcGamma *crtc_gamma, guint size)
-{
- Bool rc;
-
- /* this is per-screen, not per output which is less than ideal */
- gdk_error_trap_push ();
- egg_warning ("using PER-SCREEN gamma tables as driver is not XRANDR 1.3 compliant");
- rc = XF86VidModeSetGammaRamp (GDK_DISPLAY(), gdk_x11_get_default_screen (), size, crtc_gamma->red, crtc_gamma->green, crtc_gamma->blue);
- gdk_error_trap_pop ();
-
- return rc;
-}
-
/**
- * gcm_device_xrandr_apply_for_crtc:
+ * gcm_device_xrandr_apply_for_output:
*
* Return value: %TRUE for success;
**/
static gboolean
-gcm_device_xrandr_apply_for_crtc (GcmDeviceXrandr *device_xrandr, GnomeRRCrtc *crtc, GcmClut *clut, GError **error)
+gcm_device_xrandr_apply_for_output (GcmDeviceXrandr *device_xrandr, GcmX11Output *output, GcmClut *clut, GError **error)
{
- guint id;
gboolean ret = TRUE;
GPtrArray *array = NULL;
- XRRCrtcGamma *crtc_gamma = NULL;
+ guint16 *red = NULL;
+ guint16 *green = NULL;
+ guint16 *blue = NULL;
guint i;
GcmClutData *data;
@@ -414,32 +324,24 @@ gcm_device_xrandr_apply_for_crtc (GcmDeviceXrandr *device_xrandr, GnomeRRCrtc *c
}
/* convert to a type X understands */
- crtc_gamma = XRRAllocGamma (array->len);
+ red = g_new (guint16, array->len);
+ green = g_new (guint16, array->len);
+ blue = g_new (guint16, array->len);
for (i=0; i<array->len; i++) {
data = g_ptr_array_index (array, i);
- crtc_gamma->red[i] = data->red;
- crtc_gamma->green[i] = data->green;
- crtc_gamma->blue[i] = data->blue;
+ red[i] = data->red;
+ green[i] = data->green;
+ blue[i] = data->blue;
}
- /* get id that X recognizes */
- id = gnome_rr_crtc_get_id (crtc);
-
- /* get the value, and catch errors */
- gdk_error_trap_push ();
- XRRSetCrtcGamma (GDK_DISPLAY(), id, crtc_gamma);
- gdk_flush ();
- if (gdk_error_trap_pop ()) {
- /* some drivers support Xrandr 1.2, not 1.3 */
- ret = gcm_device_xrandr_apply_fallback (crtc_gamma, array->len);
- if (!ret) {
- g_set_error (error, 1, 0, "failed to set crtc gamma %p (%i) on %i", crtc_gamma, array->len, id);
- goto out;
- }
- }
+ /* send to LUT */
+ ret = gcm_x11_output_set_gamma (output, array->len, red, green, blue, error);
+ if (!ret)
+ goto out;
out:
- if (crtc_gamma != NULL)
- XRRFreeGamma (crtc_gamma);
+ g_free (red);
+ g_free (green);
+ g_free (blue);
if (array != NULL)
g_ptr_array_unref (array);
return ret;
@@ -477,18 +379,18 @@ gcm_device_xrandr_get_config_data (GcmDevice *device)
gboolean
gcm_device_xrandr_is_primary (GcmDeviceXrandr *device_xrandr)
{
- gint x, y;
+ guint x, y;
gboolean ret = FALSE;
- GnomeRROutput *output;
+ GcmX11Output *output;
/* check we have an output */
- output = gcm_screen_get_output_by_name (device_xrandr->priv->screen,
- device_xrandr->priv->native_device, NULL);
+ output = gcm_x11_screen_get_output_by_name (device_xrandr->priv->screen,
+ device_xrandr->priv->native_device, NULL);
if (output == NULL)
goto out;
/* is the monitor our primary monitor */
- gnome_rr_output_get_position (output, &x, &y);
+ gcm_x11_output_get_position (output, &x, &y);
ret = (x == 0 && y == 0);
out:
return ret;
@@ -505,9 +407,8 @@ gcm_device_xrandr_apply (GcmDevice *device, GError **error)
gboolean ret = FALSE;
GcmClut *clut = NULL;
GcmProfile *profile = NULL;
- GnomeRRCrtc *crtc;
- GnomeRROutput *output;
- gint x, y;
+ GcmX11Output *output;
+ guint x, y;
const gchar *filename;
gchar *filename_systemwide = NULL;
gfloat gamma_adjust;
@@ -560,21 +461,11 @@ gcm_device_xrandr_apply (GcmDevice *device, GError **error)
}
/* check we have an output */
- output = gcm_screen_get_output_by_name (priv->screen, output_name, error);
+ output = gcm_x11_screen_get_output_by_name (priv->screen, output_name, error);
if (output == NULL)
goto out;
-
- /* get crtc size */
- crtc = gnome_rr_output_get_crtc (output);
- if (crtc == NULL) {
- g_set_error (error, 1, 0, "failed to get crtc for device: %s", id);
- goto out;
- }
-
- /* get gamma table size */
- size = gcm_device_xrandr_get_gamma_size (device_xrandr, crtc, error);
- if (size == 0)
- goto out;
+ priv->gamma_size = gcm_x11_output_get_gamma_size (output);
+ size = priv->gamma_size;
/* only set the CLUT if we're not seting the atom */
use_global = g_settings_get_boolean (priv->settings, GCM_SETTINGS_GLOBAL_DISPLAY_CORRECTION);
@@ -602,12 +493,12 @@ gcm_device_xrandr_apply (GcmDevice *device, GError **error)
}
/* actually set the gamma */
- ret = gcm_device_xrandr_apply_for_crtc (device_xrandr, crtc, clut, error);
+ ret = gcm_device_xrandr_apply_for_output (device_xrandr, output, clut, error);
if (!ret)
goto out;
/* is the monitor our primary monitor */
- gnome_rr_output_get_position (output, &x, &y);
+ gcm_x11_output_get_position (output, &x, &y);
leftmost_screen = (x == 0 && y == 0);
/* either remove the atoms or set them */
@@ -619,32 +510,32 @@ gcm_device_xrandr_apply (GcmDevice *device, GError **error)
goto out;
/* remove the output atom if there's nothing to show */
- ret = gcm_xserver_remove_output_profile (priv->xserver, output_name, error);
+ ret = gcm_x11_output_remove_profile (output, error);
if (!ret)
goto out;
/* primary screen */
if (leftmost_screen) {
- ret = gcm_xserver_remove_root_window_profile (priv->xserver, error);
+ ret = gcm_x11_screen_remove_profile (priv->screen, error);
if (!ret)
goto out;
- ret = gcm_xserver_remove_protocol_version (priv->xserver, error);
+ ret = gcm_x11_screen_remove_protocol_version (priv->screen, error);
if (!ret)
goto out;
}
} else {
/* set the per-output and per screen profile atoms */
filename = gcm_profile_get_filename (profile);
- ret = gcm_xserver_set_output_profile (priv->xserver, output_name, filename, error);
+ ret = gcm_x11_output_set_profile (output, filename, error);
if (!ret)
goto out;
/* primary screen */
if (leftmost_screen) {
- ret = gcm_xserver_set_root_window_profile (priv->xserver, filename, error);
+ ret = gcm_x11_screen_set_profile (priv->screen, filename, error);
if (!ret)
goto out;
- ret = gcm_xserver_set_protocol_version (priv->xserver,
+ ret = gcm_x11_screen_set_protocol_version (priv->screen,
GCM_ICC_PROFILE_IN_X_VERSION_MAJOR,
GCM_ICC_PROFILE_IN_X_VERSION_MINOR,
error);
@@ -674,9 +565,6 @@ gcm_device_xrandr_get_property (GObject *object, guint prop_id, GValue *value, G
case PROP_NATIVE_DEVICE:
g_value_set_string (value, priv->native_device);
break;
- case PROP_XRANDR_FALLBACK:
- g_value_set_boolean (value, priv->xrandr_fallback);
- break;
case PROP_EISA_ID:
g_value_set_string (value, priv->eisa_id);
break;
@@ -735,14 +623,6 @@ gcm_device_xrandr_class_init (GcmDeviceXrandrClass *klass)
g_object_class_install_property (object_class, PROP_NATIVE_DEVICE, pspec);
/**
- * GcmDeviceXrandr:xrandr-fallback:
- */
- pspec = g_param_spec_boolean ("xrandr-fallback", NULL, NULL,
- FALSE,
- G_PARAM_READABLE);
- g_object_class_install_property (object_class, PROP_XRANDR_FALLBACK, pspec);
-
- /**
* GcmDeviceXrandr:eisa-id:
*/
pspec = g_param_spec_string ("eisa-id", NULL, NULL,
@@ -771,14 +651,12 @@ gcm_device_xrandr_init (GcmDeviceXrandr *device_xrandr)
device_xrandr->priv->native_device = NULL;
device_xrandr->priv->eisa_id = NULL;
device_xrandr->priv->edid_md5 = NULL;
- device_xrandr->priv->xrandr_fallback = FALSE;
device_xrandr->priv->remove_atom = TRUE;
device_xrandr->priv->gamma_size = 0;
device_xrandr->priv->edid = gcm_edid_new ();
device_xrandr->priv->dmi = gcm_dmi_new ();
device_xrandr->priv->settings = g_settings_new (GCM_SETTINGS_SCHEMA);
- device_xrandr->priv->screen = gcm_screen_new ();
- device_xrandr->priv->xserver = gcm_xserver_new ();
+ device_xrandr->priv->screen = gcm_x11_screen_new ();
}
/**
@@ -797,7 +675,7 @@ gcm_device_xrandr_finalize (GObject *object)
g_object_unref (priv->dmi);
g_object_unref (priv->settings);
g_object_unref (priv->screen);
- g_object_unref (priv->xserver);
+ g_object_unref (priv->screen);
G_OBJECT_CLASS (gcm_device_xrandr_parent_class)->finalize (object);
}
diff --git a/src/gcm-device-xrandr.h b/src/gcm-device-xrandr.h
index 5d61525..58434be 100644
--- a/src/gcm-device-xrandr.h
+++ b/src/gcm-device-xrandr.h
@@ -23,9 +23,9 @@
#define __GCM_DEVICE_XRANDR_H
#include <glib-object.h>
-#include <libgnomeui/gnome-rr.h>
#include "gcm-device.h"
+#include "gcm-x11-screen.h"
G_BEGIN_DECLS
@@ -51,7 +51,7 @@ struct _GcmDeviceXrandrClass
GType gcm_device_xrandr_get_type (void);
GcmDevice *gcm_device_xrandr_new (void);
gboolean gcm_device_xrandr_set_from_output (GcmDevice *device,
- GnomeRROutput *output,
+ GcmX11Output *output,
GError **error);
void gcm_device_xrandr_set_remove_atom (GcmDeviceXrandr *device_xrandr,
gboolean remove_atom);
diff --git a/src/gcm-inspect.c b/src/gcm-inspect.c
index 78f72a2..a399ba9 100644
--- a/src/gcm-inspect.c
+++ b/src/gcm-inspect.c
@@ -23,15 +23,14 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include <libgnomeui/gnome-rr.h>
#include <locale.h>
#include "egg-debug.h"
#include "gcm-utils.h"
#include "gcm-profile.h"
-#include "gcm-xserver.h"
-#include "gcm-screen.h"
+#include "gcm-x11-output.h"
+#include "gcm-x11-screen.h"
/**
* gcm_inspect_print_data_info:
@@ -76,10 +75,10 @@ gcm_inspect_show_x11_atoms (void)
guint8 *data = NULL;
guint8 *data_tmp;
gsize length;
- GcmXserver *xserver = NULL;
- GnomeRROutput **outputs;
+ GPtrArray *outputs;
+ GcmX11Output *output;
+ GcmX11Screen *screen = NULL;
guint i;
- GcmScreen *screen = NULL;
const gchar *output_name;
gchar *title;
GError *error = NULL;
@@ -87,10 +86,16 @@ gcm_inspect_show_x11_atoms (void)
guint minor;
/* setup object to access X */
- xserver = gcm_xserver_new ();
+ screen = gcm_x11_screen_new ();
+ ret = gcm_x11_screen_assign (screen, NULL, &error);
+ if (!ret) {
+ egg_warning ("failed to get outputs: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
/* get profile from XServer */
- ret = gcm_xserver_get_root_window_profile_data (xserver, &data, &length, &error);
+ ret = gcm_x11_screen_get_profile_data (screen, &data, &length, &error);
if (!ret) {
egg_warning ("failed to get XServer profile data: %s", error->message);
g_error_free (error);
@@ -102,7 +107,7 @@ gcm_inspect_show_x11_atoms (void)
}
/* get profile from XServer */
- ret = gcm_xserver_get_protocol_version (xserver, &major, &minor, &error);
+ ret = gcm_x11_screen_get_protocol_version (screen, &major, &minor, &error);
if (!ret) {
egg_warning ("failed to get XServer protocol version: %s", error->message);
g_error_free (error);
@@ -114,22 +119,22 @@ gcm_inspect_show_x11_atoms (void)
}
/* coldplug devices */
- screen = gcm_screen_new ();
- outputs = gcm_screen_get_outputs (screen, &error);
+ outputs = gcm_x11_screen_get_outputs (screen, &error);
if (outputs == NULL) {
ret = FALSE;
egg_warning ("failed to get outputs: %s", error->message);
g_error_free (error);
goto out;
}
- for (i=0; outputs[i] != NULL; i++) {
+ for (i=0; i<outputs->len; i++) {
/* get output name */
- output_name = gnome_rr_output_get_name (outputs[i]);
+ output = g_ptr_array_index (outputs, i);
+ output_name = gcm_x11_output_get_name (output);
title = g_strdup_printf (_("Output profile '%s':"), output_name);
/* get profile from XServer */
- ret = gcm_xserver_get_output_profile_data (xserver, output_name, &data_tmp, &length, &error);
+ ret = gcm_x11_output_get_profile_data (output, &data_tmp, &length, &error);
if (!ret) {
egg_warning ("failed to get output profile data: %s", error->message);
/* TRANSLATORS: this is when the profile has not been set */
@@ -148,8 +153,6 @@ out:
g_free (data);
if (screen != NULL)
g_object_unref (screen);
- if (xserver != NULL)
- g_object_unref (xserver);
return ret;
}
@@ -567,9 +570,9 @@ main (int argc, char **argv)
GOptionContext *context;
const GOptionEntry options[] = {
- { "x11", 'x', 0, G_OPTION_ARG_NONE, &x11,
+ { "xserver", 'x', 0, G_OPTION_ARG_NONE, &x11,
/* TRANSLATORS: command line option */
- _("Show X11 properties"), NULL },
+ _("Show xserver properties"), NULL },
{ "device", '\0', 0, G_OPTION_ARG_STRING, &device_id,
/* TRANSLATORS: command line option */
_("Get the profiles for a specific device"), NULL },
diff --git a/tools/Makefile.am b/tools/Makefile.am
index ac3b186..bf961f1 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -25,11 +25,11 @@ INCLUDES = \
noinst_PROGRAMS = \
gcm-dump-profile \
gcm-dump-sensor \
+ gcm-dump-edid \
gcm-fix-profile \
gcm-ddc-util \
gcm-sensor-example
-if FALSE
gcm_dump_edid_SOURCES = \
gcm-dump-edid.c
@@ -39,7 +39,6 @@ gcm_dump_edid_LDADD = \
gcm_dump_edid_CFLAGS = \
$(WARNINGFLAGS_C)
-endif
gcm_dump_profile_SOURCES = \
gcm-dump-profile.c
diff --git a/tools/gcm-dump-edid.c b/tools/gcm-dump-edid.c
index e39e8ef..eaeb778 100644
--- a/tools/gcm-dump-edid.c
+++ b/tools/gcm-dump-edid.c
@@ -23,13 +23,10 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include <libgnomeui/gnome-rr.h>
#include <locale.h>
-#include "egg-debug.h"
-
-#include "gcm-screen.h"
#include "gcm-edid.h"
+#include "gcm-x11-screen.h"
/**
* gcm_dump_edid_filename:
@@ -84,7 +81,7 @@ gcm_dump_edid_filename (const gchar *filename)
width = gcm_edid_get_width (edid);
height = gcm_edid_get_height (edid);
if (width != 0)
- g_print (" Size: %ix%i\n", "", width, height);
+ g_print (" Size: %ix%i\n", width, height);
gamma = gcm_edid_get_gamma (edid);
if (gamma > 0.0f)
g_print (" Gamma: %f\n", gamma);
@@ -96,12 +93,30 @@ out:
}
/**
+ * gcm_dump_edid_alphanum_lcase:
+ **/
+static void
+gcm_dump_edid_alphanum_lcase (gchar *data)
+{
+ guint i;
+
+ g_return_if_fail (data != NULL);
+
+ /* replace unsafe chars, and make lowercase */
+ for (i=0; data[i] != '\0'; i++) {
+ if (!g_ascii_isalnum (data[i]))
+ data[i] = '_';
+ data[i] = g_ascii_tolower (data[i]);
+ }
+}
+
+/**
* main:
**/
int
main (int argc, char **argv)
{
- const guint8 *data;
+ guint8 *data = NULL;
gboolean ret;
gchar *output_name;
gchar *filename;
@@ -109,8 +124,9 @@ main (int argc, char **argv)
guint i;
guint retval = 0;
GError *error = NULL;
- GnomeRROutput **outputs;
- GcmScreen *screen = NULL;
+ GPtrArray *outputs;
+ GcmX11Output *output;
+ GcmX11Screen *screen = NULL;
GOptionContext *context;
const GOptionEntry options[] = {
@@ -129,7 +145,6 @@ main (int argc, char **argv)
context = g_option_context_new ("gnome-color-manager dump edid program");
g_option_context_add_main_entries (context, options, NULL);
- g_option_context_add_group (context, egg_debug_get_option_group ());
g_option_context_add_group (context, gtk_get_option_group (TRUE));
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
@@ -144,28 +159,29 @@ main (int argc, char **argv)
}
/* coldplug devices */
- screen = gcm_screen_new ();
- outputs = gcm_screen_get_outputs (screen, &error);
- if (screen == NULL) {
- egg_warning ("failed to get outputs: %s", error->message);
+ screen = gcm_x11_screen_new ();
+ outputs = gcm_x11_screen_get_outputs (screen, &error);
+ if (outputs == NULL) {
+ g_print ("Failed to get outputs: %s\n", error->message);
retval = 1;
goto out;
}
- for (i=0; outputs[i] != NULL; i++) {
+ for (i=0; i<outputs->len; i++) {
/* only try to get edid if connected */
- ret = gnome_rr_output_is_connected (outputs[i]);
+ output = g_ptr_array_index (outputs, i);
+ ret = gcm_x11_output_get_connected (output);
if (!ret)
continue;
/* get data */
- data = gnome_rr_output_get_edid_data (outputs[i]);
- if (data == NULL)
+ ret = gcm_x11_output_get_edid_data (output, &data, NULL, NULL);
+ if (!ret)
continue;
/* get output name */
- output_name = g_strdup (gnome_rr_output_get_name (outputs[i]));
- gcm_utils_alphanum_lcase (output_name);
+ output_name = g_strdup (gcm_x11_output_get_name (output));
+ gcm_dump_edid_alphanum_lcase (output_name);
/* get suitable filename */
filename = g_strdup_printf ("./%s.bin", output_name);
@@ -173,16 +189,17 @@ main (int argc, char **argv)
/* save to disk */
ret = g_file_set_contents (filename, (const gchar *) data, 0x80, &error);
if (ret) {
- g_print "Saved %i bytes to %s", 128, filename);
- g_print ("\n");
+ g_print ("Saved %i bytes to %s\n", 128, filename);
gcm_dump_edid_filename (filename);
} else {
g_print ("Failed to save EDID to %s: %s\n", filename, error->message);
/* non-fatal */
g_clear_error (&error);
}
+ g_free (data);
g_free (filename);
}
+ g_ptr_array_unref (outputs);
out:
g_strfreev (files);
if (screen != NULL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]