summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: feb44ad)
raw | patch | inline | side by side (parent: feb44ad)
author | joncruz <joncruz@users.sourceforge.net> | |
Sat, 17 Nov 2007 08:56:33 +0000 (08:56 +0000) | ||
committer | joncruz <joncruz@users.sourceforge.net> | |
Sat, 17 Nov 2007 08:56:33 +0000 (08:56 +0000) |
src/Makefile_insert | patch | blob | history | |
src/ege-color-prof-tracker.cpp | [new file with mode: 0644] | patch | blob |
src/ege-color-prof-tracker.h | [new file with mode: 0644] | patch | blob |
src/widgets/desktop-widget.cpp | patch | blob | history | |
src/widgets/desktop-widget.h | patch | blob | history |
diff --git a/src/Makefile_insert b/src/Makefile_insert
index 8234498903172203784806d1811ec04dcae22603..3d5d2e55a3b8942aa62c2a807a84613ffca000be 100644 (file)
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
dir-util.cpp dir-util.h \
ege-adjustment-action.cpp \
ege-adjustment-action.h \
+ ege-color-prof-tracker.cpp \
+ ege-color-prof-tracker.h \
ege-output-action.cpp \
ege-output-action.h \
ege-select-one-action.cpp \
diff --git a/src/ege-color-prof-tracker.cpp b/src/ege-color-prof-tracker.cpp
--- /dev/null
@@ -0,0 +1,619 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is EGE Color Profile Tracker.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <string.h>
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include <gdk/gdkx.h>
+#endif /* GDK_WINDOWING_X11 */
+
+#include "ege-color-prof-tracker.h"
+
+/*
+#define GDK_ROOT_WINDOW() (gdk_x11_get_default_root_xwindow ())
+#define GDK_DISPLAY() gdk_display
+#define GDK_WINDOW_XDISPLAY(win)
+#define GDK_WINDOW_XID(win)
+#define GDK_DISPLAY_XDISPLAY(display)
+#define GDK_SCREEN_XDISPLAY(screen)
+#define GDK_SCREEN_XNUMBER(screen)
+#define GDK_SCREEN_XSCREEN(screen)
+
+#define GDK_WINDOW_XWINDOW
+#define GDK_DRAWABLE_XID(win)
+
+GdkWindow* gdk_window_lookup (GdkNativeWindow anid);
+GdkWindow* gdk_window_lookup_for_display (GdkDisplay *display,
+ GdkNativeWindow anid);
+
+GdkDisplay* gdk_x11_lookup_xdisplay (Display *xdisplay);
+
+Display* gdk_x11_display_get_xdisplay (GdkDisplay *display);
+
+Window gdk_x11_get_default_root_xwindow (void);
+gint gdk_x11_get_default_screen (void);
+Display* gdk_x11_get_default_xdisplay (void);
+int gdk_x11_screen_get_screen_number (GdkScreen *screen);
+Screen* gdk_x11_screen_get_xscreen (GdkScreen *screen);
+
+const gchar* gdk_x11_get_xatom_name (Atom xatom);
+const gchar* gdk_x11_get_xatom_name_for_display (GdkDisplay *display,
+ Atom xatom);
+ */
+
+enum {
+ CHANGED = 0,
+ LAST_SIGNAL};
+
+
+static void ege_color_prof_tracker_class_init( EgeColorProfTrackerClass* klass );
+static void ege_color_prof_tracker_init( EgeColorProfTracker* tracker );
+static void ege_color_prof_tracker_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ege_color_prof_tracker_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+
+typedef struct _ScreenTrack {
+ GdkScreen* screen;
+#ifdef GDK_WINDOWING_X11
+ gboolean zeroSeen;
+ gboolean otherSeen;
+#endif /* GDK_WINDOWING_X11 */
+ GSList* trackers;
+ GPtrArray* profiles;
+} ScreenTrack;
+
+#ifdef GDK_WINDOWING_X11
+GdkFilterReturn x11_win_filter(GdkXEvent *xevent, GdkEvent *event, gpointer data);
+void handle_property_change(GdkScreen* screen, const gchar* name);
+void add_x11_tracking_for_screen(GdkScreen* screen, ScreenTrack* screenTrack);
+#endif /* GDK_WINDOWING_X11 */
+
+static GObjectClass* gParentClass = 0;
+static guint signals[LAST_SIGNAL] = {0};
+
+static GSList* tracked_screens = 0;
+
+
+struct _EgeColorProfTrackerPrivate
+{
+ GtkWidget* _target;
+ gint _monitor;
+};
+
+#define EGE_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_COLOR_PROF_TRACKER_TYPE, EgeColorProfTrackerPrivate ) )
+
+
+static void target_finalized( gpointer data, GObject* where_the_object_was );
+static void window_finalized( gpointer data, GObject* where_the_object_was );
+static void event_after_cb( GtkWidget* widget, GdkEvent* event, gpointer user_data );
+static void target_hierarchy_changed_cb(GtkWidget* widget, GtkWidget* prev_top, gpointer user_data);
+static void target_screen_changed_cb(GtkWidget* widget, GdkScreen* prev_screen, gpointer user_data);
+static void screen_size_changed_cb(GdkScreen* screen, gpointer user_data);
+static void fire(GdkScreen* screen, gint monitor);
+static void clear_profile( GdkScreen* screen, guint monitor );
+static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, guint len );
+
+GType ege_color_prof_tracker_get_type( void )
+{
+ static GType myType = 0;
+ if ( !myType ) {
+ static const GTypeInfo myInfo = {
+ sizeof( EgeColorProfTrackerClass ),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)ege_color_prof_tracker_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof( EgeColorProfTracker ),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc)ege_color_prof_tracker_init,
+ NULL
+ };
+
+ myType = g_type_register_static( G_TYPE_OBJECT, "EgeColorProfTracker", &myInfo, (GTypeFlags)0 );
+ }
+
+ return myType;
+}
+
+void ege_color_prof_tracker_class_init( EgeColorProfTrackerClass* klass )
+{
+ if ( klass ) {
+ gParentClass = G_OBJECT_CLASS( g_type_class_peek_parent( klass ) );
+ GObjectClass* objClass = G_OBJECT_CLASS( klass );
+
+ objClass->get_property = ege_color_prof_tracker_get_property;
+ objClass->set_property = ege_color_prof_tracker_set_property;
+
+ signals[CHANGED] = g_signal_new( "changed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(EgeColorProfTrackerClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private( klass, sizeof(EgeColorProfTrackerClass) );
+ }
+}
+
+
+void ege_color_prof_tracker_init( EgeColorProfTracker* tracker )
+{
+ tracker->private_data = EGE_GET_PRIVATE( tracker );
+ tracker->private_data->_target = 0;
+ tracker->private_data->_monitor = 0;
+}
+
+EgeColorProfTracker* ege_color_prof_tracker_new( GtkWidget* target )
+{
+ GObject* obj = (GObject*)g_object_new( EGE_COLOR_PROF_TRACKER_TYPE,
+ NULL );
+
+ EgeColorProfTracker* tracker = EGE_COLOR_PROF_TRACKER( obj );
+ tracker->private_data->_target = target;
+
+ g_object_weak_ref( G_OBJECT(target), target_finalized, obj );
+ g_signal_connect( G_OBJECT(target), "hierarchy-changed", G_CALLBACK( target_hierarchy_changed_cb ), obj );
+ g_signal_connect( G_OBJECT(target), "screen-changed", G_CALLBACK( target_screen_changed_cb ), obj );
+
+ /* invoke the callbacks now to connect if the widget is already visible */
+ target_hierarchy_changed_cb( target, 0, obj );
+ target_screen_changed_cb( target, 0, obj );
+
+ return tracker;
+}
+
+void ege_color_prof_tracker_get_profile( EgeColorProfTracker const * tracker, gpointer* ptr, guint* len )
+{
+ gpointer dataPos = 0;
+ guint dataLen = 0;
+ if ( tracker && tracker->private_data->_target ) {
+ GdkScreen* screen = gtk_widget_get_screen(tracker->private_data->_target);
+ GSList* curr = tracked_screens;
+ while ( curr ) {
+ ScreenTrack* screenTrack = (ScreenTrack*)curr->data;
+ if ( screenTrack->screen == screen ) {
+ if ( tracker->private_data->_monitor >= 0 && tracker->private_data->_monitor < (gint)screenTrack->profiles->len ) {
+ GByteArray* gba = (GByteArray*)g_ptr_array_index( screenTrack->profiles, tracker->private_data->_monitor );
+ if ( gba ) {
+ dataPos = gba->data;
+ dataLen = gba->len;
+ }
+ } else {
+ g_warning("No profile data tracked for the specified item.");
+ }
+ break;
+ }
+ curr = g_slist_next(curr);
+ }
+
+ }
+ if ( ptr ) {
+ *ptr = dataPos;
+ }
+ if ( len ) {
+ *len = dataLen;
+ }
+}
+
+void ege_color_prof_tracker_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ EgeColorProfTracker* tracker = EGE_COLOR_PROF_TRACKER( obj );
+ (void)tracker;
+ (void)value;
+
+ switch ( propId ) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ege_color_prof_tracker_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ EgeColorProfTracker* tracker = EGE_COLOR_PROF_TRACKER( obj );
+ (void)tracker;
+ (void)value;
+ switch ( propId ) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+
+static void track_screen( GdkScreen* screen, EgeColorProfTracker* tracker )
+{
+ GSList* curr = tracked_screens;
+ /* First remove the tracker from different screens */
+ while ( curr ) {
+ ScreenTrack* screenTrack = (ScreenTrack*)curr->data;
+ if ( screenTrack->screen != screen ) {
+ screenTrack->trackers = g_slist_remove_all(screenTrack->trackers, tracker);
+ }
+ curr = g_slist_next(curr);
+ }
+
+ curr = tracked_screens;
+ while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) {
+ curr = g_slist_next(curr);
+ }
+
+ if ( curr ) {
+ /* We found the screen already being tracked */
+ ScreenTrack* screenTrack = (ScreenTrack*)curr->data;
+ GSList* trackHook = g_slist_find( screenTrack->trackers, tracker );
+ if ( !trackHook ) {
+ screenTrack->trackers = g_slist_append( screenTrack->trackers, tracker );
+ }
+ } else {
+ ScreenTrack* newTrack = g_new(ScreenTrack, 1);
+ gint numMonitors = gdk_screen_get_n_monitors(screen);
+ int i = 0;
+ newTrack->screen = screen;
+#ifdef GDK_WINDOWING_X11
+ newTrack->zeroSeen = FALSE;
+ newTrack->otherSeen = FALSE;
+#endif /* GDK_WINDOWING_X11 */
+ newTrack->trackers = g_slist_append( 0, tracker );
+ newTrack->profiles = g_ptr_array_new();
+ for ( i = 0; i < numMonitors; i++ ) {
+ g_ptr_array_add( newTrack->profiles, 0 );
+ }
+ tracked_screens = g_slist_append( tracked_screens, newTrack );
+
+ g_signal_connect( G_OBJECT(screen), "size-changed", G_CALLBACK( screen_size_changed_cb ), tracker );
+
+#ifdef GDK_WINDOWING_X11
+ add_x11_tracking_for_screen(screen, newTrack);
+#endif // GDK_WINDOWING_X11
+ }
+}
+
+
+void target_finalized( gpointer data, GObject* where_the_object_was )
+{
+ (void)data;
+ GSList* curr = tracked_screens;
+ while ( curr ) {
+ ScreenTrack* track = (ScreenTrack*)curr->data;
+ GSList* trackHook = track->trackers;
+ while ( trackHook ) {
+ if ( (void*)(((EgeColorProfTracker*)(trackHook->data))->private_data->_target) == (void*)where_the_object_was ) {
+ /* The tracked widget is now gone, remove it */
+ ((EgeColorProfTracker*)trackHook->data)->private_data->_target = 0;
+ track->trackers = g_slist_remove( track->trackers, trackHook );
+ trackHook = 0;
+ } else {
+ trackHook = g_slist_next( trackHook );
+ }
+ }
+
+ curr = g_slist_next( curr );
+ }
+}
+
+void window_finalized( gpointer data, GObject* where_the_object_was )
+{
+ (void)data;
+ (void)where_the_object_was;
+/* g_message("Window at %p is now going away", where_the_object_was); */
+}
+
+void event_after_cb( GtkWidget* widget, GdkEvent* event, gpointer user_data )
+{
+ if ( event->type == GDK_CONFIGURE ) {
+ GdkScreen* screen = gtk_widget_get_screen(widget);
+ GdkWindow* window = widget->window;
+ EgeColorProfTracker* tracker = (EgeColorProfTracker*)user_data;
+ gint monitorNum = gdk_screen_get_monitor_at_window(screen, window);
+ if ( monitorNum != tracker->private_data->_monitor ) {
+ tracker->private_data->_monitor = monitorNum;
+ g_signal_emit( G_OBJECT(tracker), signals[CHANGED], 0 );
+ }
+ }
+}
+
+void target_hierarchy_changed_cb(GtkWidget* widget, GtkWidget* prev_top, gpointer user_data)
+{
+ if ( !prev_top && gtk_widget_get_toplevel(widget) ) {
+ GtkWidget* top = gtk_widget_get_toplevel(widget);
+ if ( GTK_WIDGET_TOPLEVEL(top) ) {
+ GtkWindow* win = GTK_WINDOW(top);
+ g_signal_connect( G_OBJECT(win), "event-after", G_CALLBACK( event_after_cb ), user_data );
+ g_object_weak_ref( G_OBJECT(win), window_finalized, user_data );
+ }
+ }
+}
+
+void target_screen_changed_cb(GtkWidget* widget, GdkScreen* prev_screen, gpointer user_data)
+{
+ GdkScreen* screen = gtk_widget_get_screen(widget);
+
+ if ( screen && (screen != prev_screen) ) {
+ track_screen( screen, EGE_COLOR_PROF_TRACKER(user_data) );
+ }
+}
+
+void screen_size_changed_cb(GdkScreen* screen, gpointer user_data)
+{
+ GSList* curr = tracked_screens;
+ (void)user_data;
+/* g_message("screen size changed to (%d, %d) with %d monitors for obj:%p", */
+/* gdk_screen_get_width(screen), gdk_screen_get_height(screen), */
+/* gdk_screen_get_n_monitors(screen), */
+/* user_data); */
+ while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) {
+ curr = g_slist_next(curr);
+ }
+ if ( curr ) {
+ ScreenTrack* track = (ScreenTrack*)curr->data;
+ gint numMonitors = gdk_screen_get_n_monitors(screen);
+ if ( numMonitors > (gint)track->profiles->len ) {
+ guint i = 0;
+ for ( i = track->profiles->len; i < (guint)numMonitors; i++ ) {
+ g_ptr_array_add( track->profiles, 0 );
+#ifdef GDK_WINDOWING_X11
+ {
+ gchar* name = g_strdup_printf( "_ICC_PROFILE_%d", i );
+ handle_property_change( screen, name );
+ g_free(name);
+ }
+#endif /* GDK_WINDOWING_X11 */
+ }
+ } else if ( numMonitors < (gint)track->profiles->len ) {
+/* g_message("The count of monitors decreased, remove some"); */
+ }
+ }
+}
+
+void fire(GdkScreen* screen, gint monitor)
+{
+ GSList* curr = tracked_screens;
+ while ( curr ) {
+ ScreenTrack* track = (ScreenTrack*)curr->data;
+ if ( track->screen == screen) {
+ GSList* trackHook = track->trackers;
+ while ( trackHook ) {
+ EgeColorProfTracker* tracker = (EgeColorProfTracker*)(trackHook->data);
+ if ( (monitor == -1) || (tracker->private_data->_monitor == monitor) ) {
+ g_signal_emit( G_OBJECT(tracker), signals[CHANGED], 0 );
+ }
+ trackHook = g_slist_next(trackHook);
+ }
+ }
+ curr = g_slist_next(curr);
+ }
+}
+
+static void clear_profile( GdkScreen* screen, guint monitor )
+{
+ GSList* curr = tracked_screens;
+ while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) {
+ curr = g_slist_next(curr);
+ }
+ if ( curr ) {
+ ScreenTrack* track = (ScreenTrack*)curr->data;
+ guint i = 0;
+ GByteArray* previous = 0;
+ for ( i = track->profiles->len; i <= monitor; i++ ) {
+ g_ptr_array_add( track->profiles, 0 );
+ }
+ previous = (GByteArray*)g_ptr_array_index( track->profiles, monitor );
+ if ( previous ) {
+ g_byte_array_free( previous, TRUE );
+ }
+
+ track->profiles->pdata[monitor] = 0;
+ }
+}
+
+static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, guint len )
+{
+ GSList* curr = tracked_screens;
+ while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) {
+ curr = g_slist_next(curr);
+ }
+ if ( curr ) {
+ ScreenTrack* track = (ScreenTrack*)curr->data;
+ guint i = 0;
+ GByteArray* previous = 0;
+ for ( i = track->profiles->len; i <= monitor; i++ ) {
+ g_ptr_array_add( track->profiles, 0 );
+ }
+ previous = (GByteArray*)g_ptr_array_index( track->profiles, monitor );
+ if ( previous ) {
+ g_byte_array_free( previous, TRUE );
+ }
+
+ if ( data && len ) {
+ GByteArray* newBytes = g_byte_array_sized_new( len );
+ newBytes = g_byte_array_append( newBytes, data, len );
+ track->profiles->pdata[monitor] = newBytes;
+ } else {
+ track->profiles->pdata[monitor] = 0;
+ }
+ }
+}
+
+#ifdef GDK_WINDOWING_X11
+GdkFilterReturn x11_win_filter(GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent* x11 = (XEvent*)xevent;
+ (void)event;
+ (void)data;
+
+ if ( x11->type == PropertyNotify ) {
+ XPropertyEvent* note = (XPropertyEvent*)x11;
+ /*GdkAtom gatom = gdk_x11_xatom_to_atom(note->atom);*/
+ const gchar* name = gdk_x11_get_xatom_name(note->atom);
+ if ( strncmp("_ICC_PROFILE", name, 12 ) == 0 ) {
+ XEvent* native = (XEvent*)xevent;
+ Status stat = Success;
+ XWindowAttributes tmp;
+ stat = XGetWindowAttributes( native->xproperty.display, native->xproperty.window, &tmp );
+ if ( stat ) {
+ GdkDisplay* display = gdk_x11_lookup_xdisplay(native->xproperty.display);
+ if ( display ) {
+ gint screenCount = gdk_display_get_n_screens(display);
+ GdkScreen* targetScreen = 0;
+ gint i = 0;
+ for ( i = 0; i < screenCount; i++ ) {
+ GdkScreen* sc = gdk_display_get_screen( display, i );
+ if ( tmp.screen == GDK_SCREEN_XSCREEN(sc) ) {
+ targetScreen = sc;
+ }
+ }
+
+ handle_property_change( targetScreen, name );
+ }
+ } else {
+/* g_message("%d failed XGetWindowAttributes with %d", GPOINTER_TO_INT(data), stat); */
+ }
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+void handle_property_change(GdkScreen* screen, const gchar* name)
+{
+ Display* xdisplay = GDK_SCREEN_XDISPLAY(screen);
+ gint monitor = 0;
+ Atom atom = XInternAtom(xdisplay, name, True);
+ if ( strncmp("_ICC_PROFILE_", name, 13 ) == 0 ) {
+ gint64 tmp = g_ascii_strtoll(name + 13, NULL, 10);
+ if ( tmp != 0 && tmp != G_MAXINT64 && tmp != G_MININT64 ) {
+ monitor = (gint)tmp;
+ }
+ }
+ if ( atom != None ) {
+ Atom actualType = None;
+ int actualFormat = 0;
+ unsigned long size = 128 * 1042;
+ unsigned long nitems = 0;
+ unsigned long bytesAfter = 0;
+ unsigned char* prop = 0;
+
+ clear_profile( screen, monitor );
+
+ if ( XGetWindowProperty( xdisplay, GDK_WINDOW_XID(gdk_screen_get_root_window(screen)),
+ atom, 0, size, False, AnyPropertyType,
+ &actualType, &actualFormat, &nitems, &bytesAfter, &prop ) == Success ) {
+ if ( (actualType != None) && (bytesAfter + nitems) ) {
+ size = nitems + bytesAfter;
+ bytesAfter = 0;
+ nitems = 0;
+ if ( XGetWindowProperty( xdisplay, GDK_WINDOW_XID(gdk_screen_get_root_window(screen)),
+ atom, 0, size, False, AnyPropertyType,
+ &actualType, &actualFormat, &nitems, &bytesAfter, &prop ) == Success ) {
+ gpointer profile = g_memdup( prop, nitems );
+ set_profile( screen, monitor, (const guint8*)profile, nitems );
+ XFree(prop);
+ } else {
+ g_warning("Problem reading profile from root window");
+ }
+ } else {
+ /* clear it */
+ set_profile( screen, monitor, 0, 0 );
+ }
+ } else {
+ g_message("error loading profile property");
+ }
+ }
+ fire(screen, monitor);
+}
+
+void add_x11_tracking_for_screen(GdkScreen* screen, ScreenTrack* screenTrack)
+{
+ Display* xdisplay = GDK_SCREEN_XDISPLAY(screen);
+ GdkWindow* root = gdk_screen_get_root_window(screen);
+ if ( root ) {
+ Window rootWin = GDK_WINDOW_XID(root);
+ Atom baseAtom = XInternAtom(xdisplay, "_ICC_PROFILE", True);
+ int numWinProps = 0;
+ Atom* propArray = XListProperties(xdisplay, rootWin, &numWinProps);
+ gint i;
+
+ gdk_window_set_events(root, (GdkEventMask)(gdk_window_get_events(root) | GDK_PROPERTY_CHANGE_MASK));
+ gdk_window_add_filter(root, x11_win_filter, GINT_TO_POINTER(1));
+
+ /* Look for any profiles attached to this root window */
+ if ( propArray ) {
+ int j = 0;
+ gint numMonitors = gdk_screen_get_n_monitors(screen);
+
+ if ( baseAtom != None ) {
+ for ( i = 0; i < numWinProps; i++ ) {
+ if ( baseAtom == propArray[i] ) {
+ screenTrack->zeroSeen = TRUE;
+ handle_property_change( screen, "_ICC_PROFILE" );
+ }
+ }
+ } else {
+/* g_message("Base atom not found"); */
+ }
+
+ for ( i = 1; i < numMonitors; i++ ) {
+ gchar* name = g_strdup_printf("_ICC_PROFILE_%d", i);
+ Atom atom = XInternAtom(xdisplay, name, True);
+ if ( atom != None ) {
+ for ( j = 0; j < numWinProps; j++ ) {
+ if ( atom == propArray[j] ) {
+ screenTrack->otherSeen = TRUE;
+ handle_property_change( screen, name );
+ }
+ }
+ }
+ g_free(name);
+ }
+ XFree(propArray);
+ propArray = 0;
+ }
+ }
+}
+#endif /* GDK_WINDOWING_X11 */
diff --git a/src/ege-color-prof-tracker.h b/src/ege-color-prof-tracker.h
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef SEEN_EGE_COLOR_PROF_TRACKER
+#define SEEN_EGE_COLOR_PROF_TRACKER
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is EGE Color Profile Tracker.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/** \file
+ * Object used to track ICC profiles attached to monitors and update as they change.
+ */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <glib.h>
+#include <glib-object.h>
+
+
+G_BEGIN_DECLS
+
+#ifdef __cplusplus
+typedef struct _GtkWidget GtkWidget;
+#endif /* __cplusplus */
+
+#define EGE_COLOR_PROF_TRACKER_TYPE ( ege_color_prof_tracker_get_type() )
+#define EGE_COLOR_PROF_TRACKER( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), EGE_COLOR_PROF_TRACKER_TYPE, EgeColorProfTracker) )
+#define EGE_COLOR_PROF_TRACKER_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), EGE_COLOR_PROF_TRACKER_TYPE, EgeColorProfTrackerClass) )
+#define IS_EGE_COLOR_PROF_TRACKER( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), EGE_COLOR_PROF_TRACKER_TYPE) )
+#define IS_EGE_COLOR_PROF_TRACKER_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), EGE_COLOR_PROF_TRACKER_TYPE) )
+#define EGE_COLOR_PROF_TRACKER_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), EGE_COLOR_PROF_TRACKER_TYPE, EgeColorProfTrackerClass) )
+
+typedef struct _EgeColorProfTracker EgeColorProfTracker;
+typedef struct _EgeColorProfTrackerClass EgeColorProfTrackerClass;
+typedef struct _EgeColorProfTrackerPrivate EgeColorProfTrackerPrivate;
+
+/**
+ * Instance structure of EgeColorProfTracker.
+ */
+struct _EgeColorProfTracker
+{
+ /** Parent instance structure. */
+ GObject object;
+
+ /** Pointer to private instance data. */
+ EgeColorProfTrackerPrivate *private_data;
+};
+
+/**
+ * Class structure of EgeColorProfTracker.
+ */
+struct _EgeColorProfTrackerClass
+{
+ /** Parent class structure. */
+ GObjectClass parent_class;
+
+ void (*changed) (EgeColorProfTracker* tracker);
+};
+
+/** Standard Gtk type function */
+GType ege_color_prof_tracker_get_type( void );
+
+/**
+ * Creates a new EgeColorProfTracker instance.
+ */
+EgeColorProfTracker* ege_color_prof_tracker_new( GtkWidget* target );
+
+void ege_color_prof_tracker_get_profile( EgeColorProfTracker const * tracker, gpointer* ptr, guint* len );
+
+G_END_DECLS
+
+#endif /* SEEN_EGE_COLOR_PROF_TRACKER */
index 3562e7b2a8a63307f55c5dc03ef0d62f28e5d124..cdfac93f1f6f6086f145b3c3e949ca612af39db3 100644 (file)
#include "dialogs/swatches.h"
#include "conn-avoid-ref.h"
#include "ege-select-one-action.h"
+#include "ege-color-prof-tracker.h"
#if defined (SOLARIS_2_8)
#include "round.h"
static gint sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw);
+static void sp_dtw_color_profile_event(GtkWidget *widget, SPDesktopWidget *dtw);
+
static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw);
static void sp_desktop_widget_namedview_modified (SPObject *obj, guint flags, SPDesktopWidget *dtw);
dtw->vscrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (dtw->vadj));
gtk_box_pack_start (GTK_BOX (dtw->vscrollbar_box), dtw->vscrollbar, TRUE, TRUE, 0);
gtk_table_attach (GTK_TABLE (canvas_tbl), dtw->vscrollbar_box, 2, 3, 0, 2, (GtkAttachOptions)(GTK_SHRINK), (GtkAttachOptions)(GTK_FILL), 0, 0);
-
+
+ dtw->cms_adjust = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
+ SP_BUTTON_TYPE_TOGGLE,
+ NULL,
+ "swatches",
+ _("Adjust the display"),
+ dtw->tt );
+ gtk_widget_set_sensitive(dtw->cms_adjust, FALSE);
+ gtk_table_attach( GTK_TABLE(canvas_tbl), dtw->cms_adjust, 2, 3, 2, 3, (GtkAttachOptions)(GTK_SHRINK), (GtkAttachOptions)(GTK_SHRINK), 0, 0);
+
/* Canvas */
dtw->canvas = SP_CANVAS (sp_canvas_new_aa ());
GTK_WIDGET_SET_FLAGS (GTK_WIDGET (dtw->canvas), GTK_CAN_FOCUS);
gtk_table_attach (GTK_TABLE (canvas_tbl), GTK_WIDGET(dtw->canvas), 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), 0, 0);
/* Dock */
- bool create_dock =
- prefs_get_int_attribute_limited ("options.dialogtype", "value", Inkscape::UI::Dialog::FLOATING, 0, 1) ==
+ bool create_dock =
+ prefs_get_int_attribute_limited ("options.dialogtype", "value", Inkscape::UI::Dialog::FLOATING, 0, 1) ==
Inkscape::UI::Dialog::DOCK;
-
+
if (create_dock)
{
dtw->dock = new Inkscape::UI::Widget::Dock();
paned->pack1(*Glib::wrap(canvas_tbl));
paned->pack2(dtw->dock->getWidget(), Gtk::FILL);
- /* Prevent the paned from catching F6 and F8 by unsetting the default callbacks */
+ /* Prevent the paned from catching F6 and F8 by unsetting the default callbacks */
if (GtkPanedClass *paned_class = GTK_PANED_CLASS (G_OBJECT_GET_CLASS (paned->gobj()))) {
paned_class->cycle_child_focus = NULL;
paned_class->cycle_handle_focus = NULL;
}
- gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (paned->gobj()), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+ gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (paned->gobj()), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0);
} else {
- gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (canvas_tbl), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+ gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (canvas_tbl), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0);
}
//dtw->layer_selector->set_size_request(-1, SP_ICON_SIZE_BUTTON);
gtk_box_pack_start(GTK_BOX(dtw->statusbar), GTK_WIDGET(dtw->layer_selector->gobj()), FALSE, FALSE, 1);
+ dtw->_tracker = ege_color_prof_tracker_new(GTK_WIDGET(dtw->layer_selector->gobj()));
+ g_signal_connect( G_OBJECT(dtw->_tracker), "changed", G_CALLBACK(sp_dtw_color_profile_event), dtw );
+
dtw->select_status_eventbox = gtk_event_box_new ();
dtw->select_status = gtk_label_new (NULL);
#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 6
void
SPDesktopWidget::updateTitle(gchar const* uri)
{
- Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
+ Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
if (window) {
gchar const *fname = ( TRUE
@@ -572,6 +587,11 @@ sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dt
return FALSE;
}
+void sp_dtw_color_profile_event(GtkWidget */*widget*/, SPDesktopWidget */*dtw*/)
+{
+ // Handle profile changes
+}
+
void
sp_dtw_desktop_activate (SPDesktopWidget *dtw)
{
_("<span weight=\"bold\" size=\"larger\">Save changes to document \"%s\" before closing?</span>\n\n"
"If you close without saving, your changes will be discarded."),
SP_DOCUMENT_NAME(doc));
- // fix for bug 1767940:
+ // fix for bug 1767940:
GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(GTK_MESSAGE_DIALOG(dialog)->label), GTK_CAN_FOCUS);
GtkWidget *close_button;
switch (response) {
case GTK_RESPONSE_YES:
{
- Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
-
- sp_document_ref(doc);
+ Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
+
+ sp_document_ref(doc);
if (sp_file_save_document(*window, doc)) {
sp_document_unref(doc);
} else { // save dialog cancelled or save failed
sp_document_unref(doc);
return TRUE;
}
-
+
break;
}
case GTK_RESPONSE_NO:
"Do you want to save this file in another format?"),
SP_DOCUMENT_NAME(doc),
Inkscape::Extension::db.get(sp_document_repr_root(doc)->attribute("inkscape:output_extension"))->get_name());
- // fix for bug 1767940:
+ // fix for bug 1767940:
GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(GTK_MESSAGE_DIALOG(dialog)->label), GTK_CAN_FOCUS);
GtkWidget *close_button;
switch (response) {
case GTK_RESPONSE_YES:
{
- sp_document_ref(doc);
-
- Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
-
+ sp_document_ref(doc);
+
+ Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
+
if (sp_file_save_dialog(*window, doc)) {
sp_document_unref(doc);
} else { // save dialog cancelled or save failed
sp_document_unref(doc);
return TRUE;
}
-
+
break;
}
case GTK_RESPONSE_NO:
prefs_set_int_attribute("desktop.geometry", "maximized", maxed);
gint w, h, x, y;
desktop->getWindowGeometry(x, y, w, h);
- // Don't save geom for maximized windows. It
+ // Don't save geom for maximized windows. It
// just tells you the current maximized size, which is not
// as useful as whatever value it had previously.
if (!maxed && !full) {
gboolean vis = GTK_WIDGET_VISIBLE (this);
Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
-
+
if (window)
{
window->get_size (w, h);
void
SPDesktopWidget::setWindowPosition (NR::Point p)
{
- Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
-
+ Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
+
if (window)
{
window->move (gint(round(p[NR::X])), gint(round(p[NR::Y])));
void
SPDesktopWidget::setWindowSize (gint w, gint h)
{
- Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
-
+ Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
+
if (window)
{
window->set_default_size (w, h);
if (dtw->desktop->is_maximized()) {
gtk_window_unmaximize(topw);
} else {
- // Save geometry to prefs before maximizing so that
+ // Save geometry to prefs before maximizing so that
// something useful is stored there, because GTK doesn't maintain
// a separate non-maximized size.
- if (!dtw->desktop->is_iconified() && !dtw->desktop->is_fullscreen())
+ if (!dtw->desktop->is_iconified() && !dtw->desktop->is_fullscreen())
{
gint w, h, x, y;
dtw->getWindowGeometry(x, y, w, h);
gtk_window_unfullscreen(topw);
// widget layout is triggered by the resulting window_state_event
} else {
- // Save geometry to prefs before maximizing so that
+ // Save geometry to prefs before maximizing so that
// something useful is stored there, because GTK doesn't maintain
// a separate non-maximized size.
- if (!dtw->desktop->is_iconified() && !dtw->desktop->is_maximized())
+ if (!dtw->desktop->is_iconified() && !dtw->desktop->is_maximized())
{
gint w, h, x, y;
dtw->getWindowGeometry(x, y, w, h);
index 18348e594b9bf20d69c5aa9d906ada49dc23d7e6..a0b97f9d899d5e964165b75f98b6ce1045c9ba6b 100644 (file)
#include <sigc++/connection.h>
+// forward declaration
+typedef struct _EgeColorProfTracker EgeColorProfTracker;
+
+
#define SP_TYPE_DESKTOP_WIDGET (sp_desktop_widget_get_type ())
#define SP_DESKTOP_WIDGET(o) (GTK_CHECK_CAST ((o), SP_TYPE_DESKTOP_WIDGET, SPDesktopWidget))
#define SP_DESKTOP_WIDGET_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), SP_TYPE_DESKTOP_WIDGET, SPDesktopWidgetClass))
SPDesktop *desktop;
Gtk::Window *window;
-
+
// The root vbox of the window layout.
GtkWidget *vbox;
GtkWidget *hruler_box, *vruler_box; // eventboxes for setting tooltips
GtkWidget *sticky_zoom;
+ GtkWidget *cms_adjust;
GtkWidget *coord_status;
GtkWidget *coord_status_x;
GtkWidget *coord_status_y;
Inkscape::UI::Widget::SelectedStyle *selected_style;
gint coord_status_id, select_status_id;
-
+
unsigned int _interaction_disabled_counter;
SPCanvas *canvas;
Inkscape::Widgets::LayerSelector *layer_selector;
+ EgeColorProfTracker* _tracker;
+
struct WidgetStub : public Inkscape::UI::View::EditWidgetInterface {
SPDesktopWidget *_dtw;
SPDesktop *_dt;
{ _dtw->updateTitle (uri); }
virtual Gtk::Window* getWindow()
{ return _dtw->window; }
- virtual void layout()
+ virtual void layout()
{ sp_desktop_widget_layout (_dtw); }
- virtual void present()
+ virtual void present()
{ _dtw->presentWindow(); }
virtual void getGeometry (gint &x, gint &y, gint &w, gint &h)
{ _dtw->getWindowGeometry (x, y, w, h); }
{ return _dtw->shutdown(); }
virtual void destroy()
{
- if(_dtw->window != NULL)
- delete _dtw->window;
- _dtw->window = NULL;
- }
-
+ if(_dtw->window != NULL)
+ delete _dtw->window;
+ _dtw->window = NULL;
+ }
+
virtual void requestCanvasUpdate()
{ _dtw->requestCanvasUpdate(); }
virtual void requestCanvasUpdateAndWait()
};
WidgetStub *stub;
-
+
void setMessage(Inkscape::MessageType type, gchar const *message);
NR::Point window_get_pointer();
bool shutdown();