index 2496b8dd622f34eb8080b4942d0936e42920e372..900246595e25feaf949c7b3709345e75b691ab9a 100644 (file)
#include <gtk/gtkwidget.h>
#include <gtk/gtkwindow.h>
+#include <gtk/gtkmarshal.h>
#ifdef GDK_WINDOWING_X11
#include <X11/Xlib.h>
enum {
CHANGED = 0,
+ ADDED,
+ REMOVED,
+ MODIFIED,
LAST_SIGNAL};
static guint signals[LAST_SIGNAL] = {0};
static GSList* tracked_screens = 0;
-
+static GSList* abstract_trackers = 0;
struct _EgeColorProfTrackerPrivate
{
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 );
+static void track_screen( GdkScreen* screen, EgeColorProfTracker* tracker );
GType ege_color_prof_tracker_get_type( void )
{
objClass->get_property = ege_color_prof_tracker_get_property;
objClass->set_property = ege_color_prof_tracker_set_property;
+ klass->changed = 0;
signals[CHANGED] = g_signal_new( "changed",
G_TYPE_FROM_CLASS(klass),
G_STRUCT_OFFSET(EgeColorProfTrackerClass, changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ G_TYPE_NONE, 0 );
+
+ signals[ADDED] = g_signal_new( "added",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ gtk_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ signals[REMOVED] = g_signal_new( "removed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ gtk_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ signals[MODIFIED] = g_signal_new( "modified",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ gtk_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
g_type_class_add_private( klass, sizeof(EgeColorProfTrackerClass) );
}
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 );
+ if ( 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 );
+ /* 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 );
+ } else {
+ abstract_trackers = g_slist_append( abstract_trackers, obj );
+
+ GSList* curr = tracked_screens;
+ while ( curr ) {
+ ScreenTrack* track = (ScreenTrack*)curr->data;
+ gint screenNum = gdk_screen_get_number(track->screen);
+ gint monitor = 0;
+ for ( monitor = 0; monitor < (gint)track->profiles->len; monitor++ ) {
+ g_signal_emit( G_OBJECT(tracker), signals[MODIFIED], 0, screenNum, monitor );
+ }
+
+ curr = g_slist_next(curr);
+ }
+
+ }
return tracker;
}
@@ -240,6 +293,43 @@ void ege_color_prof_tracker_get_profile( EgeColorProfTracker const * tracker, gp
}
}
+void ege_color_prof_tracker_get_profile_for( guint screenNum, guint monitor, gpointer* ptr, guint* len )
+{
+ gpointer dataPos = 0;
+ guint dataLen = 0;
+ GdkDisplay* display = gdk_display_get_default();
+ gint numScreens = gdk_display_get_n_screens(display);
+ GdkScreen* screen = (screenNum < (guint)numScreens) ? gdk_display_get_screen(display, screenNum) : 0;
+
+ if ( screen ) {
+ GSList* curr = tracked_screens;
+ while ( curr ) {
+ ScreenTrack* screenTrack = (ScreenTrack*)curr->data;
+ if ( screenTrack->screen == screen ) {
+ if ( monitor < screenTrack->profiles->len ) {
+ GByteArray* gba = (GByteArray*)g_ptr_array_index( screenTrack->profiles, 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 );
@@ -264,7 +354,7 @@ void ege_color_prof_tracker_set_property( GObject* obj, guint propId, const GVal
}
-static void track_screen( GdkScreen* screen, EgeColorProfTracker* tracker )
+void track_screen( GdkScreen* screen, EgeColorProfTracker* tracker )
{
GSList* curr = tracked_screens;
/* First remove the tracker from different screens */
@@ -457,9 +547,13 @@ static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, g
curr = g_slist_next(curr);
}
if ( curr ) {
+ /* Something happened to a screen being tracked. */
ScreenTrack* track = (ScreenTrack*)curr->data;
+ gint screenNum = gdk_screen_get_number(screen);
guint i = 0;
GByteArray* previous = 0;
+ GSList* abstracts = 0;
+
for ( i = track->profiles->len; i <= monitor; i++ ) {
g_ptr_array_add( track->profiles, 0 );
}
@@ -475,6 +569,10 @@ static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, g
} else {
track->profiles->pdata[monitor] = 0;
}
+
+ for ( abstracts = abstract_trackers; abstracts; abstracts = g_slist_next(abstracts) ) {
+ g_signal_emit( G_OBJECT(abstracts->data), signals[MODIFIED], 0, screenNum, monitor );
+ }
}
}
size = nitems + bytesAfter;
bytesAfter = 0;
nitems = 0;
+ if ( prop ) {
+ XFree(prop);
+ prop = 0;
+ }
if ( XGetWindowProperty( xdisplay, GDK_WINDOW_XID(gdk_screen_get_root_window(screen)),
atom, 0, size, False, AnyPropertyType,
&actualType, &actualFormat, &nitems, &bytesAfter, &prop ) == Success ) {
set_profile( screen, monitor, 0, 0 );
}
} else {
- g_message("error loading profile property");
+ g_warning("error loading profile property");
}
}
fire(screen, monitor);