Compare commits
5 Commits
matthiasc/
...
wip/paint-
Author | SHA1 | Date | |
---|---|---|---|
|
c52cbb18d6 | ||
|
85608e903f | ||
|
55b2f3ab4e | ||
|
079366259a | ||
|
76db970f8e |
@@ -632,7 +632,12 @@ gdk_threads_add_timeout
|
||||
gdk_threads_add_timeout_full
|
||||
gdk_threads_add_timeout_seconds
|
||||
gdk_threads_add_timeout_seconds_full
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_threads_get_periodic
|
||||
gdk_threads_set_periodic
|
||||
gdk_threads_periodic_add
|
||||
gdk_threads_periodic_remove
|
||||
gdk_threads_periodic_damaged
|
||||
<SUBSECTION Private>
|
||||
gdk_threads_lock
|
||||
gdk_threads_unlock
|
||||
|
189
gdk/gdk.c
189
gdk/gdk.c
@@ -1,5 +1,6 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright © 2010 Codethink Limited
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -65,6 +66,7 @@ static int gdk_initialized = 0; /* 1 if the library is initialized,
|
||||
static gchar *gdk_progclass = NULL;
|
||||
|
||||
static GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */
|
||||
static GPeriodic *gdk_threads_periodic; /* Default paint clock */
|
||||
|
||||
static GCallback gdk_threads_lock = NULL;
|
||||
static GCallback gdk_threads_unlock = NULL;
|
||||
@@ -809,3 +811,190 @@ gdk_enable_multidevice (void)
|
||||
|
||||
_gdk_enable_multidevice = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_threads_set_periodic:
|
||||
* @periodic: a #GPeriodic, non-%NULL
|
||||
*
|
||||
* Sets the default #GPeriodic clock in use by GDK. GDK takes a
|
||||
* reference on @periodic and it lives forever.
|
||||
*
|
||||
* You may not replace the default #GPeriodic once it has been set, so
|
||||
* you should check with gdk_threads_get_periodic() to ensure that it is
|
||||
* %NULL before attempting to call this function.
|
||||
*
|
||||
* gtk_init() will set the default clock if it has not already been set,
|
||||
* so you need to call this function before you call gtk_init().
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gdk_threads_set_periodic (GPeriodic *periodic)
|
||||
{
|
||||
g_return_if_fail (gdk_threads_periodic == NULL);
|
||||
g_return_if_fail (periodic != NULL);
|
||||
|
||||
gdk_threads_periodic = g_object_ref (periodic);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_threads_get_periodic:
|
||||
*
|
||||
* Gets the default #GPeriodic in use by GDK, or %NULL if one has not
|
||||
* been set yet.
|
||||
*
|
||||
* GDK owns the return value, so you should not unref it.
|
||||
*
|
||||
* Returns: (transfer none): the default #GPeriodic, or %NULL
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GPeriodic *
|
||||
gdk_threads_get_periodic (void)
|
||||
{
|
||||
return gdk_threads_periodic;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GPeriodicTickFunc callback;
|
||||
gpointer user_data;
|
||||
GDestroyNotify notify;
|
||||
} GdkPeriodicTick;
|
||||
|
||||
static void
|
||||
gdk_periodic_tick (GPeriodic *periodic,
|
||||
guint64 timestamp,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkPeriodicTick *tick = user_data;
|
||||
|
||||
gdk_threads_enter ();
|
||||
tick->callback (periodic, timestamp, tick->user_data);
|
||||
/* Do not touch 'tick' anymore.
|
||||
* It might have been freed by the callback removing itself.
|
||||
*/
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_periodic_tick_free (gpointer data)
|
||||
{
|
||||
GdkPeriodicTick *tick = data;
|
||||
|
||||
if (tick->notify)
|
||||
tick->notify (tick->user_data);
|
||||
|
||||
g_slice_free (GdkPeriodicTick, tick);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_threads_periodic_add:
|
||||
* @callback: a #GPeriodicTickFunc
|
||||
* @user_data: data for @callback
|
||||
* @notify: for freeing @user_data when it is no longer needed
|
||||
*
|
||||
* Request periodic calls to @callback to start. @callback is called
|
||||
* with the GDK lock held.
|
||||
*
|
||||
* This function may not be called while a repair function is running,
|
||||
* but it is perfectly reasonable to call it from a tick function.
|
||||
*
|
||||
* The callback may be cancelled later by using
|
||||
* gdk_threads_periodic_remove().
|
||||
*
|
||||
* Returns: a non-zero tag identifying this callback
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
guint
|
||||
gdk_threads_periodic_add (GPeriodicTickFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
GdkPeriodicTick *tick;
|
||||
|
||||
tick = g_slice_new (GdkPeriodicTick);
|
||||
tick->callback = callback;
|
||||
tick->user_data = user_data;
|
||||
tick->notify = notify;
|
||||
|
||||
return g_periodic_add (gdk_threads_periodic, gdk_periodic_tick,
|
||||
tick, gdk_periodic_tick_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_threads_periodic_remove:
|
||||
* @tag: the ID of the callback to
|
||||
*
|
||||
* Reverse the effect of a previous call to gdk_threads_periodic_add().
|
||||
*
|
||||
* @tag is the ID returned by that function.
|
||||
*
|
||||
* This function may not be called while a repair function is running,
|
||||
* but it is perfectly reasonable to call it from a tick function.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gdk_threads_periodic_remove (guint tag)
|
||||
{
|
||||
g_periodic_remove (gdk_threads_periodic, tag);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GPeriodicRepairFunc callback;
|
||||
gpointer user_data;
|
||||
GDestroyNotify notify;
|
||||
} GdkPeriodicRepair;
|
||||
|
||||
static void
|
||||
gdk_periodic_repair (GPeriodic *periodic,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkPeriodicRepair *repair = user_data;
|
||||
|
||||
gdk_threads_enter ();
|
||||
repair->callback (periodic, repair->user_data);
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_periodic_repair_free (gpointer data)
|
||||
{
|
||||
GdkPeriodicRepair *repair = data;
|
||||
|
||||
if (repair->notify)
|
||||
repair->notify (repair->user_data);
|
||||
|
||||
g_slice_free (GdkPeriodicRepair, repair);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_threads_periodic_damaged:
|
||||
* @callback: a #GPeriodicRepairFunc
|
||||
* @user_data: data for @callback
|
||||
* @notify: for freeing @user_data when it is no longer needed
|
||||
*
|
||||
* Reports damage to the GDK default #GPeriodic.
|
||||
*
|
||||
* @callback is called with the GDK lock held.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gdk_threads_periodic_damaged (GPeriodicRepairFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
GdkPeriodicRepair *repair;
|
||||
|
||||
repair = g_slice_new (GdkPeriodicRepair);
|
||||
repair->callback = callback;
|
||||
repair->user_data = user_data;
|
||||
repair->notify = notify;
|
||||
|
||||
g_periodic_damaged (gdk_threads_periodic, gdk_periodic_repair,
|
||||
repair, gdk_periodic_repair_free);
|
||||
}
|
||||
|
@@ -192,6 +192,11 @@ gdk_threads_add_timeout
|
||||
gdk_threads_add_timeout_full
|
||||
gdk_threads_add_timeout_seconds
|
||||
gdk_threads_add_timeout_seconds_full
|
||||
gdk_threads_set_periodic
|
||||
gdk_threads_get_periodic
|
||||
gdk_threads_periodic_add
|
||||
gdk_threads_periodic_remove
|
||||
gdk_threads_periodic_damaged
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright © 2010 Codethink Limited
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -64,6 +65,16 @@ guint gdk_threads_add_timeout_seconds (guint interval,
|
||||
GSourceFunc function,
|
||||
gpointer data);
|
||||
|
||||
void gdk_threads_set_periodic (GPeriodic *periodic);
|
||||
GPeriodic * gdk_threads_get_periodic (void);
|
||||
guint gdk_threads_periodic_add (GPeriodicTickFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
void gdk_threads_periodic_remove (guint tag);
|
||||
void gdk_threads_periodic_damaged (GPeriodicRepairFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
#define GDK_THREADS_ENTER() gdk_threads_enter()
|
||||
#define GDK_THREADS_LEAVE() gdk_threads_leave()
|
||||
|
||||
|
@@ -3760,7 +3760,7 @@ gdk_window_set_cairo_clip (GdkDrawable *drawable,
|
||||
/* Code for dirty-region queueing
|
||||
*/
|
||||
static GSList *update_windows = NULL;
|
||||
static guint update_idle = 0;
|
||||
static gboolean damage_reported;
|
||||
static gboolean debug_updates = FALSE;
|
||||
|
||||
static inline gboolean
|
||||
@@ -3859,12 +3859,12 @@ gdk_window_remove_update_window (GdkWindow *window)
|
||||
update_windows = g_slist_remove (update_windows, window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_window_update_idle (gpointer data)
|
||||
static void
|
||||
gdk_window_repair (GPeriodic *periodic,
|
||||
gpointer user_data)
|
||||
{
|
||||
gdk_window_process_all_updates ();
|
||||
|
||||
return FALSE;
|
||||
damage_reported = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3885,11 +3885,11 @@ gdk_window_schedule_update (GdkWindow *window)
|
||||
gdk_window_is_toplevel_frozen (window)))
|
||||
return;
|
||||
|
||||
if (!update_idle)
|
||||
update_idle =
|
||||
gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
|
||||
gdk_window_update_idle,
|
||||
NULL, NULL);
|
||||
if (!damage_reported)
|
||||
{
|
||||
gdk_threads_periodic_damaged (gdk_window_repair, NULL, NULL);
|
||||
damage_reported = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4212,18 +4212,15 @@ gdk_window_process_all_updates (void)
|
||||
/* We can't do this now since that would recurse, so
|
||||
delay it until after the recursion is done. */
|
||||
got_recursive_update = TRUE;
|
||||
update_idle = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
in_process_all_updates = TRUE;
|
||||
got_recursive_update = FALSE;
|
||||
|
||||
if (update_idle)
|
||||
g_source_remove (update_idle);
|
||||
/* We can't unreport damage, so let it run anyway. */
|
||||
|
||||
update_windows = NULL;
|
||||
update_idle = 0;
|
||||
|
||||
_gdk_windowing_before_process_all_updates ();
|
||||
|
||||
@@ -4258,11 +4255,11 @@ gdk_window_process_all_updates (void)
|
||||
redraw now so that it eventually happens,
|
||||
otherwise we could miss an update if nothing
|
||||
else schedules an update. */
|
||||
if (got_recursive_update && !update_idle)
|
||||
update_idle =
|
||||
gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
|
||||
gdk_window_update_idle,
|
||||
NULL, NULL);
|
||||
if (got_recursive_update && !damage_reported)
|
||||
{
|
||||
gdk_threads_periodic_damaged (gdk_window_repair, NULL, NULL);
|
||||
damage_reported = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1068,6 +1068,9 @@ gtk_init_check (int *argc,
|
||||
if (!gtk_parse_args (argc, argv))
|
||||
return FALSE;
|
||||
|
||||
if (gdk_threads_get_periodic () == NULL)
|
||||
gdk_threads_set_periodic (g_periodic_new (60, GDK_PRIORITY_REDRAW));
|
||||
|
||||
return gdk_display_open_default_libgtk_only () != NULL;
|
||||
}
|
||||
|
||||
|
@@ -66,7 +66,7 @@ struct _GtkSpinnerPrivate
|
||||
guint num_steps;
|
||||
guint cycle_duration;
|
||||
gboolean active;
|
||||
guint timeout;
|
||||
guint tag;
|
||||
};
|
||||
|
||||
static void gtk_spinner_dispose (GObject *gobject);
|
||||
@@ -211,9 +211,6 @@ gtk_spinner_init (GtkSpinner *spinner)
|
||||
priv = G_TYPE_INSTANCE_GET_PRIVATE (spinner,
|
||||
GTK_TYPE_SPINNER,
|
||||
GtkSpinnerPrivate);
|
||||
priv->current = 0;
|
||||
priv->timeout = 0;
|
||||
|
||||
spinner->priv = priv;
|
||||
|
||||
gtk_widget_set_has_window (GTK_WIDGET (spinner), FALSE);
|
||||
@@ -269,42 +266,34 @@ gtk_spinner_draw (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_spinner_timeout (gpointer data)
|
||||
static void
|
||||
gtk_spinner_tick (GPeriodic *periodic,
|
||||
guint64 timestamp,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkSpinnerPrivate *priv;
|
||||
guint duration;
|
||||
|
||||
priv = GTK_SPINNER (data)->priv;
|
||||
priv = GTK_SPINNER (user_data)->priv;
|
||||
|
||||
if (priv->current + 1 >= priv->num_steps)
|
||||
priv->current = 0;
|
||||
else
|
||||
priv->current++;
|
||||
duration = priv->cycle_duration * 1000;
|
||||
priv->current = (timestamp % duration) / (duration / priv->num_steps);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (data));
|
||||
|
||||
return TRUE;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spinner_add_timeout (GtkSpinner *spinner)
|
||||
{
|
||||
GtkSpinnerPrivate *priv;
|
||||
|
||||
priv = spinner->priv;
|
||||
|
||||
priv->timeout = gdk_threads_add_timeout ((guint) priv->cycle_duration / priv->num_steps, gtk_spinner_timeout, spinner);
|
||||
spinner->priv->tag =
|
||||
gdk_threads_periodic_add (gtk_spinner_tick, spinner, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spinner_remove_timeout (GtkSpinner *spinner)
|
||||
{
|
||||
GtkSpinnerPrivate *priv;
|
||||
|
||||
priv = spinner->priv;
|
||||
|
||||
g_source_remove (priv->timeout);
|
||||
priv->timeout = 0;
|
||||
gdk_threads_periodic_remove (spinner->priv->tag);
|
||||
spinner->priv->tag = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -325,7 +314,7 @@ gtk_spinner_unmap (GtkWidget *widget)
|
||||
GtkSpinner *spinner = GTK_SPINNER (widget);
|
||||
GtkSpinnerPrivate *priv = spinner->priv;
|
||||
|
||||
if (priv->timeout != 0)
|
||||
if (priv->tag != 0)
|
||||
gtk_spinner_remove_timeout (spinner);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_spinner_parent_class)->unmap (widget);
|
||||
@@ -355,7 +344,7 @@ gtk_spinner_dispose (GObject *gobject)
|
||||
|
||||
priv = GTK_SPINNER (gobject)->priv;
|
||||
|
||||
if (priv->timeout != 0)
|
||||
if (priv->tag != 0)
|
||||
{
|
||||
gtk_spinner_remove_timeout (GTK_SPINNER (gobject));
|
||||
}
|
||||
@@ -377,11 +366,11 @@ gtk_spinner_set_active (GtkSpinner *spinner, gboolean active)
|
||||
priv->active = active;
|
||||
g_object_notify (G_OBJECT (spinner), "active");
|
||||
|
||||
if (active && gtk_widget_get_realized (GTK_WIDGET (spinner)) && priv->timeout == 0)
|
||||
if (active && gtk_widget_get_realized (GTK_WIDGET (spinner)) && priv->tag == 0)
|
||||
{
|
||||
gtk_spinner_add_timeout (spinner);
|
||||
}
|
||||
else if (!active && priv->timeout != 0)
|
||||
else if (!active && priv->tag != 0)
|
||||
{
|
||||
gtk_spinner_remove_timeout (spinner);
|
||||
}
|
||||
|
Reference in New Issue
Block a user